I wrote a code expecting to receive error along with the description expression must be a modifiable value but i didn't, I don't understand can arrays that were dynamically allocated be modified?
{
int* x;
x =(int*) malloc(3 * sizeof(int));
if (x == 0)
{
printf("sorry met an error");
exit(1);
}
x[0] = 0;
x[1] = 1;
x[2] = 2;
printf("%p\n", x);
printf("%d\n", x[0]);
printf("%d\n", sizeof(x));
x ;
printf("%p\n", x);
printf("%d\n", x[0]);
printf("%d\n", x[1]);
printf("%d", sizeof(x));
free(x);
return 0;
}
By the way the free function here is also triggering a breakpoint any ideas why?
CodePudding user response:
x
is a pointer to the first element in an array. (x
is not an array.)
As x
is not const
, you are free to modify it. x
modifies it to point to the second element in the array.
When you then attempt to free the dynamically-allocated array (free(x)
) you are passing free()
a value that malloc
did not give you. Hence the debugger triggering a break.
Either restore x
to its prior value before attempting to free it, or use a different pointer variable to play arithmetic and leave x
alone.
CodePudding user response:
compiling with 'gcc' command line:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" -o "untitled.o"
linked with the command line:
gcc -ggdb3 -o "untitled" "untitled.o"
modified code, with comments
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int* x;
x = malloc(3 * sizeof(int));
// in C, the memory allocation functions (malloc, calloc, realloc)
// returned type is 'void*' which can be assigned to any pointer
// so casting just clutters the code and is error prone.
if (!x)
{
perror("sorry met an error");
// the 'perror' function outputs to 'stderr' the text meaning of
// the 'errno' variable plus the text supplied by the parameter.
// note: in the current scenario 'errno' was set by 'malloc'
exit( EXIT_FAILURE );
// EXIT_FAILURE is defined in stdlib.h'
}
x[0] = 0;
x[1] = 1;
x[2] = 2;
printf("%p\n", (void*)x);
// %p requires a 'void*' parameter
printf("%d\n", x[0]);
printf("%zu\n", sizeof(x));
// sizeof returns a 'long unsigned int' value
// which is printable via '%zu'
x ;
// this modifies the pointer returned via 'malloc'
// it does not change where the array is located in memory
printf("%p\n", (void*)x);
printf("%d\n", x[0]);
printf("%d\n", x[1]);
printf("%zu", sizeof(x));
free(x);
// the pointer to the array has been changed
// so this will fail at runtime
return 0;
}
with the modified code, the following is the output
0x562e604882a0
0
8
0x562e604882a4
1
2
free(): invalid pointer
Aborted (core dumped)