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\":
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.
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");
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 tofree
orrealloc
, 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.
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
.
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
.