Skip to main content
GameDev.net gamedev.net
🔒 Locked

char* = char[]

Started by Zeophlite Dec 31, 2004 at 9:07 PM 23 replies 3.3k views
Original Post
Zeophlite
Zeophlite

char blah[255];
blah = "foobar";
char* meh;

sprintf(meh,"%s",blah);
printf("%s",meh);

Output: (null) Whats wrong with my code?
mike25025
mike25025
try

char* meh = new char[256];
C-Junkie
C-Junkie
also, blah isn't initialized to anything...
Drew_Benton
Drew_Benton
The code:

char blah[255];
blah = "foobar";
char* meh;

sprintf(meh,"%s",blah);
printf("%s",meh);


Is not correct! I'm suprised it does not crash. Here is an alternative:

char blah[255];
sprintf(blah,"foobar");
printf(blah);

the variable meh serves no purpose in this example - it is used as a temporary buffer but it is not sized so it will not work. If you wanted the orig code to work right:


char blah[255];
sprintf(blah,"foobar");
char meh[1024]; // large over kill buffer :)

sprintf(meh,"%s",blah);
printf("%s",meh);

As a side note - you are probabally using Debug mode - which initilizes everything to 0. If you try it in release mode it would crash undoubtedly. I hope this helps some!

- Drew
Hedos
Hedos
char[] == char*
Except for the fact that a char[] is a pointer which will always point to a correct emplacement containing memory for the array, while your char*, by default, does not point anywhere unless you allocate memory with 'new'.
Zeophlite
Zeophlite
But is their any way to make keep meh, char* meh?
I'd prefer to keep it char* meh instead of char meh[1024];
Hedos
Hedos
As mike25025 showed, you must allocate some memory if you want to store data through "meh"
char* meh = new char[256];

And don't forget to delete[] it..
Zeophlite
Zeophlite
I see,

In that cases, how do I set the function type for a function that returns a char array:

char meh() {
char goo[12];
...
return goo;
}

What would I change "char meh() {" to, to allow it to return a char array?
Hedos
Hedos
char *meh()
{
char MyChar[12];
//..
return MyChar;
}


That would be the syntaxically correct function, though, returning a local variable might not be a good idea.
Doc
Doc
Use std::string instead. Seriously. You're just asking for trouble, otherwise.

std::string meh() { std::string ret_val; // Assign ret_val in here somewhere. return ret_val;}
Xai
Xai
MIGHT not is a light way to say it :)

char blah[255]; // creates an array of 255 chars on the stack (or if global, then in the data section of the programblah = "foobar"; // this is incorrect and should not even compile, you cannot change what an array points to.sprintf(blah,"%s","foobar"); // copy the contents of the constant string foobar into the character array blahchar blah2[255] = "foobar"; // a special case (using the = operator on a declaration line IS NOT the same as calling = later), this allocates 255 chars with the initial values of: {'f','o','o','b','a','r','\0', ???}// i can't remember if the values after the null terminator are undefined, or if they are all initialized to 0 (I think 0).char* meh; // declares a pointer to character(s)sprintf(meh,"%s",blah); // error, you are copying characters into where??? wherever meh points, which is either 0, or a random memory address ...char *meh2 = "foobar"; // this allocated a char pointer pointing to the constant  string "foobar" - KIND OF like the character array earlier, except this does not allocate space on the stack, and you are not allowed to change the contents of "foobar"sprintf(meh2,"%s",blah); // error, you are copying characters into a contant string ... not legalmeh2 = blah2; // valid, this makes meh2 POINT to the character array blah2printf("%s",meh);char *meh3; // allocate a pointermeh3 = new char[strlen(blah)]; // allocated a character array just big enough to hold "foobar"strcpy(meh3,"%s",blah); // copy the contents of blah into the buffer pointed to by meh3

Drew_Benton
Drew_Benton
Quote:
Original post by Doc
Use std::string instead. Seriously. You're just asking for trouble, otherwise.

*** Source Snippet Removed ***


Seconded like there is no tomorrow!
Zahlman
Zahlman
Quote:
Original post by Anonymous Poster
Quote:
Original post by Zeophlite
Whats wrong with my code?


You need to add "meh = &blah[0];" before the sprintf.

It should work perfectly without any other changes.


This is so wrong I just have to laugh. Xai is correct on all counts, AFAICT, except that of course the last 'strcpy' should be 'sprintf' (given that set of arguments, anyway).

Quote:
Original post by Drew_Benton
Quote:
Original post by Doc
Use std::string instead. Seriously. You're just asking for trouble, otherwise.

*** Source Snippet Removed ***

Seconded like there is no tomorrow!


And thirded. Assuming you are able to use C++. In which case, use streams as well (instead of the C-style *print* family of functions).

Anyway. You cannot return an array AFAIK, and you cannot safely return a pointer to a local auto (not static) variable. You could, of course, cause the function to allocate some space, and return a pointer thereto; but then you need to establish (in non-GC languages) who is responsible for freeing that memory.
blizzard999
blizzard999
Quote:
Original post by Zahlman
And thirded. Assuming you are able to use C++. In which case, use streams as well (instead of the C-style *print* family of functions).


Probably it should be better starting to study C.
It is incredible to write 5 errors in 5 lines of code. :) :)
Your 'NULL' output was commented by other people...

Second question:

Quote:


I see,

In that cases, how do I set the function type for a function that returns a char array:

char meh() {
char goo[12];
...
return goo;
}

What would I change "char meh() {" to, to allow it to return a char array?


You get a compiler error because goo is of type (char*) that is a POINTER that is a memory address to a character.
You should modify your return type to (char*).
Now you will probably get a runtime error because goo is a ptr to an array of 12
char but it is created on the stack. When you exit from the function the stack is destroyed and the ptr is invalid (outside).

// "C++" codechar* meh(void){   char* goo = (char*)malloc(12*sizeof(char)); // optional:a char is always 1 byte   return(goo); // goo is now valid because it is resident on the heap}...char* pchar = (char*)malloc(12);...// when you no more need the array remember to free itfree(pchar);// now pchar is invalid!
Pipo DeClown
Pipo DeClown
Quote:
Original post by Zahlman
Quote:
Original post by Anonymous Poster
You need to add "meh = &blah[0];" before the sprintf.

It should work perfectly without any other changes.


This is so wrong I just have to laugh.


Uhm.. No?
BTW, The way you replied is so wrong that I just have to laugh.
v0dKA
v0dKA
To answer your second question, study this program:

#include <iostream>char* ReturnString();int main(){	char* pString = ReturnString();		// Get the string	std::cout << "The string out of the function: " << pString << std::endl;	// Output it	delete pString;		// Delete the allocated memory	return 0;}char* ReturnString(){	char szString[ 256 ];	// Since you wanted to work with char arrays, and not pointers, we initialize an array	// If working with char* instead isn't a problem, you don't need this, as well as a few other lines in the function		strcpy( &szString[ 0 ], "foobar" );		// ... work with the char array	// ...continue working with the char array	char* pfString = new char[ 256 ];		// Create a dynamic char* that you can return	strcpy( pfString, (char*)szString );	// Copy char array into it	std::cout << "The string within the function: " << pfString << std::endl;	// Just to make sure	return pfString;	// Return the char*}


As you can see, the main problem here is converting the char[] into a char*, which is done in this line:
strcpy( pfString, (char*)szString );


Besides that, everything else is explained in the comments.
Also, in case you're not familiar with this line:
strcpy( &szString[ 0 ], "foobar" );

You're copying 'f','o','o','b','a','r','\0' into the memory location of the first element of the char array. You obtain the first element by the [ 0 ], and you specify you want the memory location by the &.

Besides that, just use std::string [wink]
.:-v0d[KA]-:. <<>>
Wyrframe
Wyrframe
char blah[255];/* This is fine. Declares a constant pointer to non-constant data, of 255 bytes length, on the stack. */blah = "foobar";/* This won't work, and should not compile. You cannot assign a new value to a constant pointer. */char* meh;/* This is fine. Declare a non-constant pointer to non-constant data. Yes, there is a real difference between "const char *" and "char const *"; the first is an alterable pointer which points at constant data, and the second is a constant pointer which points at alterable data. */sprintf(meh,"%s",blah);/* Syntactically correct, but assuming the mistakes with blah have been corrected, you're still writing data to the uninitialized and likely unallocated location in memory which meh supposedly looks at. */printf("%s",meh);/* Would work fine if meh pointed at anything. As it is, it's a pointer to unallocated junk data. */
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Cibressus
Cibressus
i don't use arrays much, but could'nt you just go

char *data = "some data";

instead of

char *data = new char[sizeof("some data")];
Zahlman
Zahlman
Quote:
Original post by Pipo DeClown
Quote:
Original post by Zahlman
Quote:
Original post by Anonymous Poster
You need to add "meh = &blah[0];" before the sprintf.

It should work perfectly without any other changes.


This is so wrong I just have to laugh.


Uhm.. No?
BTW, The way you replied is so wrong that I just have to laugh.


The original code has bugs, which Xai and many others pointed out, and the suggested inclusion cannot prevent those problems.

The statement "meh = &blah[0];" (which is equivalent to "meh = blah;") does not do what the OP wants - it will make meh point at the array data, when the OP clearly wants meh to point at a separate copy of that data.

"adding it before the sprintf" is just silly, as a result - why make a pointer point at an array and then sprintf the array contents to the location indicated by the pointer? The sprintf becomes a no-op. Of course, it will still end up outputting the desired text and will therefore "work perfectly" - except that it won't, because the previous assignment of the string literal to the char array is still wrong!

I made an attempt to demonstrate that I know whereof I speak. You are hereby challenged to follow suit.

Cibressus: I think compilers will allow that, but they probably shouldn't - to be pedantic, the string literal is in static storage, and you aren't guaranteed to be able to modify it - thus you should only be able to declare a const char * in that way. Meanwhile, the allocation of 'new char[sizeof("some data")]' is wrong AFAICT; since "some data" is not an array, the sizeof will resolve to 'sizeof char*', which is probably 4. And in any case you would still have to actually write the data into the allocated space.

All of which (and more) is why rational, sane people use std::string in C++.
Pipo DeClown
Pipo DeClown
Quote:
Original post by Zahlman
The original code has bugs, which Xai and many others pointed out, and the suggested inclusion cannot prevent those problems.

The statement "meh = &blah[0];" (which is equivalent to "meh = blah;") does not do what the OP wants - it will make meh point at the array data, when the OP clearly wants meh to point at a separate copy of that data.

"adding it before the sprintf" is just silly, as a result - why make a pointer point at an array and then sprintf the array contents to the location indicated by the pointer? The sprintf becomes a no-op. Of course, it will still end up outputting the desired text and will therefore "work perfectly" - except that it won't, because the previous assignment of the string literal to the char array is still wrong!

I made an attempt to demonstrate that I know whereof I speak. You are hereby challenged to follow suit.


There is no need to challenge, because I just misunderstood. But the way you replied at first is easy to misunderstand, you could've said that whole thing earlier. Anyway, I thought you were saying the syntax is wrong and bad, and did not know you were talking about the result not being the OPs wanted result.

Cya!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.