Pointer to string changes its value unexpectedly

后端 未结 4 1455
执念已碎
执念已碎 2021-01-26 18:32

I have noted that, when writing a string in an array allocated with malloc(), its value changes. To be clear, here is the code that replicates this \"error\":

相关标签:
4条回答
  • 2021-01-26 19:11

    Your problem

    You are allocating memory for your pointer with malloc() but then you assign your pointer variable to something else ("something", which has its own address), instead of filling the newly-allocated pointer.

    Solution

    You should use the strdup() function that allocates memory and copies a string at the allocated memory:

    a_p = strdup("something");
    

    Or the strcpy() function, that takes a malloc()'d pointer and a string to copy in the pointed memory:

    a_p = malloc(N * sizeof(char));
    strcpy(a_p, "something");
    
    0 讨论(0)
  • 2021-01-26 19:11

    Well the literal string are basically arrays and it decayed into pointer to the first element when you assigned it to a_p. That address is being printed.

    And as you dont keep the address of the allocated memory you are having memory leak.

    Also you cant use it in free and that gives enough hint that it is not allocated dynamically . From standard

    The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

    Well this explains why you faced problem when trying to free memory you haven't allocated.

    Again to have something like copying you need to use strcpy or strncpy or strdup(POSIX compliant).

    For more information check this link. Standard says it explicitly how it is considered as array in translation steps.

    Especially this part - ( Decayed pointer is of type char* that's why)

    For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence.

    0 讨论(0)
  • 2021-01-26 19:26

    The string literal "something" represents a null-terminated series of characters that live in some read-only region (most likely .text if you build/link/run on a GNU/Linux system).

    Initially, a_p points to somewhere in the memory region within which malloc is allocating buffers. You can freely write to the location to which a_p points, free() it, etc. When you perform the assignment a_p = "something";, you are not writing characters to the location to which a_p points, but rather changing that pointer to point to the beginning of that string. Now, you're pointing into (read-only) memory that wasn't allocated by malloc so its corresponding free function isn't able to do anything meaningful.

    Use strcpy (or better yet for safety, strncpy) instead to copy characters to the destination, a_p.

    0 讨论(0)
  • 2021-01-26 19:35

    You are changing the pointer directly. This statement

    a_p = "something";
    

    is equivalent to

    a_p = &"something"[0];
    

    String literals have types of character arrays. For example the string literal "something" has type char[10].

    From the C Standard (6.4.5 String literals)

    6 In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence...

    Used in expressions arrays with rare exceptions are converted to pointers to their first elements.

    From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

    3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

    So after this statement

    a_p = "something";
    

    the pointer points to the first character of the string literal with the static storage duration.

    I think you mean

    strcpy( a_p, "something" );
    

    That is you wanted to copy the string literal in the dynamically allocated memory.

    Take into account that if even you'll write the following code

    char *p1 = "string";
    char *p2 = "string";
    

    then it is not necessary that p1 is equal to p2 because depending on compiler options the compiler can place these two identical string literals in different memory extents.

    So the if statement

    if ( p1 == p2 )
    

    can yield either true or false.

    0 讨论(0)
提交回复
热议问题