views:

103

answers:

5
main(){
   char *cmd1[20] = {NULL};
   int x = parse_command(cmd1);
   printf("%s\ ",cmd1[0]);
}

parse_command(char *inTempString){
   char tempString[256];
   (call to function that assigns a string to tempString)
   cmd1[0] = tempString;
}

There is a problem when printing out the cmd1[0] within main. I am pretty sure that it is a dangling pointer error. I don't really know how to go about fixing it. Any help would be greatly appreciated. Thank you.

A: 

You're declaring cmd1 in main as a char** -- that is, a pointer to pointer to char. However, you then pass it to parse_command, which you've defined as taking a char*; a pointer to char.

This only compiles because of automatic conversion of pointer-to-anything to pointer-to-char. That's a historical artifact of old versions of C that used 'char*' in place of 'void*'; in your case, it just means that the compiler is ignoring the type error that you made rather than reporting it to you.

Brooks Moses
`cmd1` is not declared `char **`. It's an array of pointers. When passed to a function, it decays to a pointer to the first element of the array, which is `char **`.
Alok
A: 

Yeah, you can't do that.

char tempString[256];

declares a variable on the stack in the function parse_command, that variable goes out of scope and pointers to it cease to be valid when parse_command returns.

You need to allocate the command string on the heap, so that it will still be valid when parse_command returns. This is one way.

parse_command(char *inTempString){
   char tempString[256];
   (call to function that assigns a string to tempString)

   int cb = strlen(tempString)+1;
   cmd1[0] = (char *)malloc(cb);
   strcpy(cmd1[0], tempString);
}

You should also call free(cmd[0]) before main exits.

In addition to that, this code doesn't compile. You can't reference cmd1[0] from inside the parse_command function. You should be getting a type mismatch when you try and pass cmd1 into parse_command, If you mean to return a char* from parse_command then it should be declared to take a char** as an argument, more like this.

parse_command(char **pcmd){
   char tempString[256];
   (call to function that assigns a string to tempString)

   int cb = strlen(tempString)+1;
   pcmd[0] = (char *)malloc(cb);
   strcpy(pcmd[0], tempString);
}
John Knoeller
Why not allocate tempString on the heap in the first place, rather than allocating it on the stack and copying it to the heap after it's created? (Possible answer: I see that you're only allocating however much space on the heap it actually uses, rather than the whole 256 bytes, which is admirable but seems to obfuscate what's happening.)
Brooks Moses
@Brooks: yes, on the assumption that most of the 256 bytes isn't needed most of the time, we go ahead and read into the stack and then decide how much to allocate.
John Knoeller
A: 

Something like this will work:

parse_command(char **inTempString){
        static char tempString[256];
        strcpy(tempString,"some string you want to copy");
        inTempString[0] = tempString;
}
  • In your code the tempString would not exist once the function returns. You need to keep it alive even after the function returns. You can allocate the space dynamically and de-allocate later or you can declare it as static.
  • Also you need to change the type argument inTempString from char* to char**.
codaddict
This works, but it only works _once_. I'm not sure this is a good recommendation to someone who is struggling with pointers.
John Knoeller
A: 

You are trying to access cmd1 variable that is inside main function from parse_command.

I would say that at least the cmd1[0] will look like an integer because it is not declared withing that method.

The cmd1 is declared as array of char* but the parameter to method is char* which might be a pointer to char array but not pointer to array of char*.

The best way to copy char array into another char array is to use either memcpy,strcpy or similar methods that accept pointers to src, dest and size to be copied.

stefanB
+5  A: 
Alok
Am I missing something, or is cmd1 not in scope in parse_command? Edit: I see that this is fixed.
chradcliffe
@chradcliffe: yeah, I didn't realize that until I started reading my own answer. :-)
Alok
+1, but Hmm, be careful where you state that "the name of an array is actually a pointer to its first element", when you actually mean that the "value" of the array is a pointer to the first element of that array.
Mustapha Isyaku-Rabiu
@rogue: true, I could be clearer. I have edited my answer. In C, the value of an array is always a pointer to its first element. I was trying to say that the name of an array used as a value is a pointer, and as an object is not. Now I have clarified it and also put in a link to another, more detailed answer of mine. Thanks for the comment.
Alok