【发布时间】:2015-08-05 01:10:23
【问题描述】:
我在 mac ox 上。我正在尝试编译这个简单的动态数组程序,但是我在 realloc 上遇到了分段错误,我相信当我尝试增加我的数组时
这里是代码
#include <stdio.h>
#include <stdlib.h>
enum { MAX_SIZE = 5 };
typedef struct dynamic_array{
int maxsize;
int size;
int* items;
}DArray;
extern int init(DArray *DAP);
extern void add(DArray *DAP, int val);
extern void addToSize(DArray *DAP,int val);
extern void destroy(DArray *DAP);
extern void print(DArray *DAP);
static int full(DArray *DAP);
static int grow(DArray *DAP);
int init(DArray* DAP)
{
DAP->items = (int*)malloc(sizeof(int) * MAX_SIZE);
if(DAP->items == NULL)
{
printf(" ALLOCATION OF DAP ITEMS NOT SUCCUESSFULL \n ");
return 0;
}
DAP->maxsize = MAX_SIZE;
DAP->size = 0; //initial size -> 0
return 1;
}
void print(DArray* DAP)
{
int i;
for(i = 0; i < DAP->size; i++)
{
int* itemLocation = (DAP->items + sizeof(int) * i);
printf(" \n ITEM AT LOCATION %d is %d \n ",i,*itemLocation);
}
}
void add(DArray* DAP,int value)
{
//add item at the end of the array, we can get the position by size counter?
if(full(DAP) == 0)
{
addToSize(DAP,value);
}
else
{
printf(" \n ********************* REALLOCATING AS SIZE == MAX SIZE %d %d ********************* \n ",DAP->size, DAP->maxsize);
int result = grow(DAP) == 1 ? 1 : 0;
if(result == 0)
{
printf(" \n ********************* GROW NOT SUCCESSFULL ********************* \n " );
}else if(result == 1)
{
printf(" \n ********************* GROW SUCCESSFULL *************************** \n ");
addToSize(DAP,value);
}
else
exit(1);
}
}
int full(DArray* DAP)
{
int result = DAP->size == DAP->maxsize ? 1 : 0;
return result;
}
void addToSize(DArray* DAP,int value)
{
int* location = DAP->items + DAP->size;
*location = value+1;
printf(" \n AFTER ADDING TO ITEMS, location, VALUE %d %d \n ", DAP->size,*location);
DAP->size++;
}
int grow(DArray* DAP)
{
int* temp = (int *)realloc(DAP->items,DAP->maxsize * sizeof(int) * 2);
if(!temp)
{
printf(" ********************* REALLOC NOT SUCCESSFULL ********************* \n ");
return 0;
}
else
{
DAP->items = temp;
DAP->maxsize *= 2;
//sanity check
printf(" \n ********************* AFTER REALLOCATION CHECK AGAIN ********************* \n ");
print(DAP);
return 1;
}
}
void destroy(DArray* DAP)
{
if(DAP != NULL)
{
if(DAP->items != NULL)
{
free(DAP->items);
DAP->items = 0;
DAP->maxsize = 0;
DAP->size = 0;
}
}
}
int main()
{
DArray darray;
if(init(&darray) == 1)
{
int i;
for(i = 0; i < 10; i++)
{
add(&darray,i);
}
}
print(&darray);
destroy(&darray);
return 0;
}
现在奇怪的部分是在我的第二个参数的 realloc 中,我将 size 元素声明为 -> DAP->maxsize * sizeof(int) * 2,当调用数组增长时它会引发分段错误。现在奇怪的是,如果我尝试删除其中一个常量来乘以 DAP->maxsize * sizeof(int) 之类的东西,那么它不会引发分段错误错误。我不确定我的代码或其他地方是否有问题。
********* 发现问题*********
问题出在 addToSize 函数内部。将代码行从 int* location = DAP->items + (sizeof(int) * DAP->size); 更改为 int* location = DAP->items + DAP->size; 解决了它。显然 sizeof(int) 导致一些垃圾值在 realloc 中传递。感谢艾伦!
【问题讨论】:
-
您是否通过 gdb 运行您的程序?
-
在
init调用中取消引用空指针 -
标准警告:不要像
malloc和朋友返回的那样投射void *。 C 不是 C++。 -
在您的代码中有很多
(DAP->items + sizeof(int) * i);会超出范围。增量使用指针类型,因此DAP->items + i;在这些情况下是您想要的。 -
addToSize():int* location = DAP->items + (sizeof(int) * DAP->size);中的内存损坏。应该是int* location = DAP->items + DAP->size;。稍后可能会导致垃圾值被传递给realloc。
标签: c arrays memory-management