char* = char[]

Started by
23 comments, last by Staffan E 19 years, 3 months ago
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

Advertisement
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!
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.
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.
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!
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.
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]->>:.
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.
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")];
| Member of UBAAG (Unban aftermath Association of Gamedev)
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++.

This topic is closed to new replies.

Advertisement