So I was trying to pormpt the user to type in a number, and then store that value in a dynamic array. Here is the code first:
#include <stdio.h>
#include <stdlib.h>
//dynamically grow the array
void growArray(int *arr, int *size){
//double the size of the array
printf("Resizing array\n");
int *temp = malloc( *size * 2 * sizeof(int));
printf("Malloc was succesfuly\n");
int i;
for (i = 0; i < *size; i++)
temp[i] = arr[i];
printf("About to free arr\n");
printf("arr: %p", arr);
printf("temp: %p", temp);
free(arr);
arr = malloc( *size * 2 * sizeof(int));
printf("About to change value to arr\n");
arr = temp;
free(temp);
printf("About to change the value of size\n");
*size *= 2;
printf("New size: %d\n", *size);
}
int main(){
int *dynamicArr;
int *size;
*size = 1;
dynamicArr = (int*) malloc(sizeof(int));
int value, i;
i = 0;
do{
printf("\nPlease enter in a int value: ");
scanf("%d", &value);
//check if the array needs to be resizesd;
printf("Checking if size if sufficient\n");
if (i >= *size)
growArray(dynamicArr, size);
if (value != -999){
printf("Adding value to the array\n");
dynamicArr[i] = value;
i ++;
}
}while(value != -999);
for (i = 0; i < *size; i++){
printf("Value of dynamicArr[%d]: %d\n", i, dynamicArr[i]);
}
return 0;
}
As you can see, I have a bunch of print statements, that I so I can see at what point my program is at, and what it is current doing. So, the program initially works. I am able to add in 8 values successfully (and resize the array 3 times, going from size 1 to size 8). But when I add in my 9 value, it has to resize the array, in which the method growArray() is called. But, for some reason I get the following error:
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000000e69010 ***
Segmentation fault (core dumped)
Before the error, the printf("About to free arr") works, but printf("arr: %p", arr); isn't called.
I have no idea why this is happening, some help would be much appreciated.
You code should probably look more like this:
#include <stdio.h>
#include <stdlib.h>
int main() {
int size = 1;
int *dynamicArr = malloc(size * sizeof(*dynamicArr));
int idx = 0;
while (1) {
int value;
printf("\nPlease enter in a int value: ");
scanf("%d", &value);
if (value == -999) {
break;
}
//check if the array needs to be resizesd
printf("Checking if size if sufficient\n");
if (idx >= size) {
size *= 2;
dynamicArr = realloc(dynamicArr, size * sizeof(*dynamicArr));
}
printf("Adding value to the array\n");
dynamicArr[idx++] = value;
}
int i;
for (i = 0; i < idx; i++) {
printf("Value of dynamicArr[%d]: %d\n", i, dynamicArr[i]);
}
free(dynamicArr);
return 0;
}
Or if you want to stick with your implementation:
#include <stdio.h>
#include <stdlib.h>
//dynamically grow the array
void growArray(int **arr, int *size){
//double the size of the array
printf("Resizing array\n");
int *temp = malloc( *size * 2 * sizeof(int));
printf("Malloc was succesfuly\n");
int i;
for (i = 0; i < *size; i++)
temp[i] = (*arr)[i];
printf("About to free arr\n");
printf("arr: %p\n", *arr);
printf("temp: %p\n", temp);
free(*arr);
printf("About to change value to arr\n");
*arr = temp;
printf("About to change the value of size\n");
*size *= 2;
printf("New size: %d\n", *size);
}
int main() {
int size = 1;
int *dynamicArr = malloc(size * sizeof(*dynamicArr));
int idx = 0;
while (1) {
int value;
printf("\nPlease enter in a int value: ");
scanf("%d", &value);
if (value == -999) {
break;
}
//check if the array needs to be resizesd;
printf("Checking if size if sufficient\n");
if (idx >= size) {
growArray(&dynamicArr, &size);
}
printf("Adding value to the array\n");
dynamicArr[idx++] = value;
}
int i;
for (i = 0; i < idx; i++){
printf("Value of dynamicArr[%d]: %d\n", i, dynamicArr[i]);
}
free(dynamicArr);
return 0;
}
BTW, you can use memcpy to copy the whole existing array to the temp array.
There are a couple of problems in your original code.
(a) The parameter arr
is passed to growArray
by value, so your assignments arr = malloc(...)
and arr = temp
are not updating the variable referenced in main()
only the copy that is local to growArray
. On the other hand, when you call free(arr)
you are freeing the buffer pointed to by the variable dynamicArr
in main()
. This is the immediate cause of your segfault.
(b) When you assign arr = temp
then free(temp);
you leak the buffer you malloc()
ed just above, then free the buffer you assigned arr
to point to (leaving it dangling).
void growArray(int *arr, int *size){
When entering growArray
, arr
points to a buffer, A
...
int *temp = malloc( *size * 2 * sizeof(int));
temp
is initialized to point to a new buffer, B
...
free(arr);
the original buffer, A, is freed. The local variable arr
is now a dangling pointer, as is whatever pointer the caller holds that was passed into this routine by value.
arr = malloc( *size * 2 * sizeof(int));
arr
is set to a freshly allocated buffer, C.
...
arr = temp;
arr
is set to alias temp
, pointing to the buffer B. The buffer C is leaked.
free(temp);
Buffer B, pointed to by both temp
and arr
is freed. They are both now dangling pointers. When arr
is later
...
}
Both tmp
and arr
go out of scope. The buffers B and C are leaked.
int main(){
int *dynamicArr;
int *size;
*size = 1;
dynamicArr = (int*) malloc(sizeof(int));
dynamicArr points to a malloced buffer ... do{ ... if(...){ growArray(dynamicArr, size); ... }
The first time this if condition passes, the value of dynamicArr
is passed as the argument arr
to growArray. growArray
frees the buffer it points to and then allocs and leaks some memory without affecting the local value of dynamicArr
. dynamicArr
is now a dangling pointer.
if (value != -999){
...
dynamicArr[i] = value;
And then this accesses the dangling pointer and segfaults.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.