0

I've written a wrap of a realloc() function in C, but the program gives me segmentation fault. The signal is caused by a WRITE memory access. Hint: address points to the zero page. Is it a dereferencing of NULL pointer on line p[i] = i * 2;?

int reallocmem(int *p,size_t newsize){
    void *q;
    q = realloc(p,newsize);
    if(q != NULL){
        p = q;
        return 1;
    }
    return 0;
}
int main(void)
{
    int *p = 0x0;
    if(!reallocmem(p,10*sizeof(int))){
        fprintf(stderr,"Could not reallocate memory\n");

    }           
    int i;
    int size = 10;
    for(i = 0;i<size;i++){
        p[i] = i * 2;
    }

    for(i = 0;i<size;i++){
        printf("%d\n",p[i]);
    }
    free(p);

}
3
  • 2
    changes made to p does not reflect after the reallocmem() call. you need to pass a double pointer Commented Jun 27, 2021 at 4:07
  • regarding: if(!reallocmem(p,10*sizeof(int))){ fprintf(stderr,"Could not reallocate memory\n"); } do not continue to exec the program if the function: reallocmem() fails Commented Jun 27, 2021 at 5:26
  • regarding: int *p = 0x0; if(!reallocmem(p,10*sizeof(int))){ to change the contents of a pointer, need t pass the address of the pointer, similar to: int *p = 0x0; if(!reallocmem(&p,10*sizeof(int))){ and the function: reallocmem() needs to be modified to access through that parameter to the original pointer Commented Jun 27, 2021 at 5:30

2 Answers 2

3

The value of p in main hasn't been changed after calling the function reallocmem, so a segmentation fault happened because the program tries to dereference the NULL pointer.

To pass a pointer as an argument and change it, we need to pass a pointer of the pointer:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int reallocmem(int **p, size_t newsize) {
  void *q;
  q = realloc(*p, newsize);
  if (q != NULL) {
    *p = q;
    return 1;
  }
  return 0;
}
int main(void) {
  int *p = 0x0;
  if (!reallocmem(&p, 10 * sizeof(int))) {
    fprintf(stderr, "Could not reallocate memory\n");
    free(p);
    return 0;
  }
  int i;
  int size = 10;
  for (i = 0; i < size; i++) {
    p[i] = i * 2;
  }

  for (i = 0; i < size; i++) {
    printf("%d\n", p[i]);
  }
  free(p);
}

Online demo


The C program passes every argument by value, if you add printf statement in your code, you will find that the p in reallocmem have a different address with the p in main, so in order to change the p in main, we need to pass the address of p(pointer to pointer) but not the value of p. Or the local copy of p in reallocmem has been changed, but it won't affect the caller function main.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int reallocmem(int *p, size_t newsize) {
  printf("%p\n", &p);
  void *q;
  q = realloc(p, newsize);
  if (q != NULL) {
    p = q;
    return 1;
  }
  return 0;
}
int main(void) {
  int *p = 0x0;
  printf("%p\n", &p);
  if (!reallocmem(p, 10 * sizeof(int))) {
    fprintf(stderr, "Could not reallocate memory\n");
  }
  int i;
  int size = 10;
  for (i = 0; i < size; i++) {
    p[i] = i * 2;
  }

  for (i = 0; i < size; i++) {
    printf("%d\n", p[i]);
  }
  free(p);
}
Sign up to request clarification or add additional context in comments.

5 Comments

thank you! So in the original code the pointer wasn't affected that's why it was giving segmentation fault? Because I was trying to dereferencing p,wich was 0x0?
@victor0x3E7 Excatlly! I will update the answer.
Upon the error of reallocmem(), you should exit from the program and not continue. Here you merely display "Could not reallocate memory" and you continue to run...
@RachidK. Thank you so much for pointing out that, I have fixed it.
Moreover realloc() does not deallocate the memory space when it returns NULL. So, when realloc(p, ...) fails, p still point on a valid memory space if it was not NULL before the call. To avoid memory leaks, some action should be taken in the error case : possibly free(p).
0

On top of previous answers, to avoid memory leaks in the error branches, action must be taken when realloc() returns NULL as according to the manual:

If realloc() fails, the original block is left untouched; it is not freed or moved.

So, when realloc(p, ...) returns NULL, the error branch should free what was pointed by 'p' (if it was not NULL before the call) when it is not planed to use 'p' any more...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.