Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用realloc()时数据已损坏_C_Malloc_Dynamic Arrays_Realloc - Fatal编程技术网

使用realloc()时数据已损坏

使用realloc()时数据已损坏,c,malloc,dynamic-arrays,realloc,C,Malloc,Dynamic Arrays,Realloc,在类的项目中,我需要增加void指针的动态数组的容量。目前,我在使用realloc时遇到了破坏用户数据的问题 void dynarray_insert(struct dynarray* da, void* val) { int i; int size = da->size; int cap = da->capacity; /*if there is no more room*/ if (size == cap) { cap

在类的项目中,我需要增加void指针的动态数组的容量。目前,我在使用realloc时遇到了破坏用户数据的问题

void dynarray_insert(struct dynarray* da, void* val) {
    int i;
    int size = da->size;
    int cap = da->capacity;


    /*if there is no more room*/
    if (size == cap) {
        cap = cap * 2;                  /*double capacity*/
        void** temp = realloc(da, sizeof(void*) * cap);

        da->data = temp;
    }

    /*if there is room*/
    else if (size < cap) {
        da->data[size] = val;
    }

    size++;

    da->size = size;
    da->capacity = cap;

  return;
}
这是dynarray结构

编辑:现在我已经修复了realloc的目标,我有一个来自realloc的内存泄漏

==474== HEAP SUMMARY:
==474==     in use at exit: 64 bytes in 1 blocks
==474==   total heap usage: 15 allocs, 14 frees, 848 bytes allocated
==474==
==474== 64 bytes in 1 blocks are definitely lost in loss record 1 of 1
==474==    at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==474==    by 0x1098E3: dynarray_insert (dynarray.c:96)
==474==    by 0x109303: test_dynarray (test_dynarray.c:39)
==474==    by 0x1097B6: main (test_dynarray.c:136)
==474==
==474== LEAK SUMMARY:
==474==    definitely lost: 64 bytes in 1 blocks
==474==    indirectly lost: 0 bytes in 0 blocks
==474==      possibly lost: 0 bytes in 0 blocks
==474==    still reachable: 0 bytes in 0 blocks
==474==         suppressed: 0 bytes in 0 blocks

这可能来自何方?

有多个问题:

  • 您不是在重新分配元素数组,而是在重新分配
    dynarray
    结构本身
  • 如果重新分配数组,则不存储元素:if很容易像您那样分离
    else
    子句
  • 您没有检查
    0
    初始容量:
    cap*2
    仍将是
    0
以下是修改后的版本:

#include <stdlib.h>

struct dynarray {
    void **data;
    int size;
    int capacity;
};

int dynarray_insert(struct dynarray *da, void *val) {
    int size = da->size;
    int cap = da->capacity;

    if (size == cap) {            /* if there is no more room */
        cap = cap ? cap * 2 : 8;  /* double capacity, special case for zero */
        void **temp = realloc(da->data, sizeof(void *) * cap);
        if (temp == NULL) {
            return -1;   /* return -1 upon realloc failure */
        }
        da->cap = cap;
        da->data = temp;
    }
    da->data[size] = val;
    return da->size++;   /* return the index of the new element if successful */
}
#包括
结构动态{
作废**数据;
整数大小;
国际能力;
};
int dynarray_insert(结构dynarray*da,void*val){
int size=da->size;
int cap=da->容量;
如果(大小==上限){/*如果没有更多的空间*/
cap=cap?cap*2:8;/*双容量,零的特殊情况*/
void**temp=realloc(da->data,sizeof(void*)*cap);
if(temp==NULL){
返回-1;/*realloc失败时返回-1*/
}
da->cap=cap;
da->数据=温度;
}
da->data[size]=val;
return da->size++;/*如果成功,则返回新元素的索引*/
}

If
realloc(da,sizeof(void*)*cap)成功,则不再允许您访问
da
——因此下一行(
da->data=temp;
)调用未定义的行为。虽然这部分代码总体上看起来很奇怪,但您想在这里做什么呢?再看一眼,我怀疑您想
realloac(da->data
而不是
da
?感谢您的快速响应。我已经修复了重新分配数组和else子句。在赋值的限制范围内,我无法更改函数的返回类型。这使它正常工作,但现在我有内存泄漏。Gdb说它来自realloc。另外,您能解释一下:cap=cap吗?cap*2:8;问号运算符在这里做什么?@JulianGilmour:三元运算符等价于
if(cap!=0){cap=cap*2;}else{cap=8;}
。释放
dynarray
结构的函数中可能存在内存泄漏:必须释放
da->data
da
本身(如果已分配)。您应该发布完整的程序。最后,内存泄漏是由于试图释放dynarray->data中的每个空指针而不是整个block分配给dynarray->data的内存。@JulianGilmour:事实上,您必须定义动态数组中各个指针的生命周期,或者在释放
dynarray
结构时释放所有指针,或者不释放任何指针,您必须在其他地方处理它们。
#include <stdlib.h>

struct dynarray {
    void **data;
    int size;
    int capacity;
};

int dynarray_insert(struct dynarray *da, void *val) {
    int size = da->size;
    int cap = da->capacity;

    if (size == cap) {            /* if there is no more room */
        cap = cap ? cap * 2 : 8;  /* double capacity, special case for zero */
        void **temp = realloc(da->data, sizeof(void *) * cap);
        if (temp == NULL) {
            return -1;   /* return -1 upon realloc failure */
        }
        da->cap = cap;
        da->data = temp;
    }
    da->data[size] = val;
    return da->size++;   /* return the index of the new element if successful */
}