0

I got a _CrtIsValidHeapPointer error with my code. And I finally find out what caused the trouble.
I use the example below to illustrate it:

char* c=(char*)malloc(20*sizeof(char));
//cout<<&c<<endl;
c="hello world";
//cout<<&c<<endl;  //if you uncomment the 2 clauses,you'll see the address is the same
                                  //which means the string literal is in the heap
cout<<c<<endl;
free(c);

1) It seemed that spaces used by string literals can't be freed? Why?

2)What't the method do you use to assign valee to array of char?
ps: I use sprintf(c,"hello world"); that works fine. But any better way?


After read the answers. I realize that I misunderstand the meaning of &c.
I should use printf("%p\n",c); instead.

duleshi
  • 1,966
  • 2
  • 21
  • 32
  • 1
    possible duplicate of [How to correctly assign a new String value in C](http://stackoverflow.com/questions/3131319/how-to-correctly-assign-a-new-string-value-in-c) – Jens Gustedt Aug 01 '12 at 10:09
  • @JensGustedt :They do have some connections and similarities. But I don't think it's a duplicate. Thanks for your link anyway, it's useful. – duleshi Aug 01 '12 at 10:36

4 Answers4

7

You should copy the string using strcpy.

The assignment c="hello world" doesn't copy the contents of the string, but assigns the address of the string literal to the pointer c. When you call free(c) afterwards, the pointer is not a valid heap address any more.

//if you uncomment the 2 clauses,you'll see the address is the same

What you see is not the value of pointer c, but the address of the pointer, which is obviously the same.

Andriy
  • 8,486
  • 3
  • 27
  • 51
6

You need to use strcpy, or a safer version strncpy. Note that with strncpy, you have to NUL-terminate the string yourself in case there was not enough space.

Examples:

char *some_other_string = ...;
int len = strlen(some_other_string);
char *c = malloc((len + 1) * sizeof(*c));
if (c == NULL)
    // handle error

strcpy(c, some_other_string);

free(c);

Note that in this case, we know there is enough space in c, so we can use strcpy. If we don't know, you can cut the string up to where you can handle it:

char *some_other_string = ...;
char *c = malloc((MAX_LEN + 1) * sizeof(*c));
if (c == NULL)
    // handle error

strncpy(c, some_other_string, MAX_LEN);
c[MAX_LEN] = '\0';

free(c);

Note that in the case of strncpy, if there is not enough space, the string is not NUL-terminated and you have to do it manually.


Side note:

&c is the address of variable c. It has nothing to do with its contents, so no matter what you do with c, &c will not change.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • You meant `c[MAX_LEN - 1]` instead of `c[MAX_LEN]`. – ouah Aug 01 '12 at 09:39
  • @ouah, no I meant to allocate `MAX_LEN + 1` memory for `c`, but thanks for pointing that out! – Shahbaz Aug 01 '12 at 09:48
  • @Shahbaz: I think this would be correct, `c[MAX_LEN + 1] = '\0';` because we want to put endline to end of the variable space. – Reza Ebrahimi Feb 01 '13 at 22:18
  • 1
    @reza, in C, when you take an array of size `n`, you have access to indices 0 to `n-1`. Since I allocated `MAX_LEN + 1` elements, the last element I can legally access is at index `MAX_LEN`. – Shahbaz Feb 01 '13 at 23:53
3
c = "hello world";

You are modidying the c pointer to the pointer to the "hello world" string literal. This does not copy the string but just modify the c pointer. You have to use the strcpy function to copy a string in an array of char.

strcpy(c, "hello world");
ouah
  • 142,963
  • 15
  • 272
  • 331
0

If you use the C++ part of the language, this is all handled by the std::string in the C++ standard library.

std::string c = "hello world"; 
cout << c << endl;

Done!

You don't have to manage anything manually.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203