Home > Software engineering >  I operated on the name of the array and didn't get error or warnings why?
I operated on the name of the array and didn't get error or warnings why?

Time:05-03

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)
  • Related