Sign in to follow this  

char* = char[]

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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'.

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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 program

blah = "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 blah

char 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 legal

meh2 = blah2; // valid, this makes meh2 POINT to the character array blah2
printf("%s",meh);

char *meh3; // allocate a pointer

meh3 = 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


Share this post


Link to post
Share on other sites
Guest 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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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++" code
char* 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 it
free(pchar);
// now pchar is invalid!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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. */

Share this post


Link to post
Share on other sites
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++.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.


Of course, it will still end up outputting the desired text and will therefore "work perfectly"


QED.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman

All of which (and more) is why rational, sane people use std::string in C++.


Then I really must go check with my local mental institution. I've never thought myself as very irrational or insane, and neither have people around me to my knowledge. Still I do use char arrays instead of std::string since I'm fluent with them.

/Staffan

Share this post


Link to post
Share on other sites
There are other explanations besides irrationality or insanity, of course [smile] Just don't come crying to me when you have to track down the bugs [wink]

Share this post


Link to post
Share on other sites

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this