如何在realloc之后清空新内存

如何在realloc之后清空新内存,c,null,memory-management,C,Null,Memory Management,调用realloc后,在保持最初分配的内存完好无损的情况下,将新内存归零的最佳方法是什么 #include <stdlib.h> #include <assert.h> #include <string.h> #include <stdio.h> size_t COLORCOUNT = 4; typedef struct rgb_t { int r; int g; int b; } rgb_t; rgb_t** col

调用realloc后,在保持最初分配的内存完好无损的情况下,将新内存归零的最佳方法是什么

#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

size_t COLORCOUNT = 4;

typedef struct rgb_t {
    int r;
    int g;
    int b;
} rgb_t;

rgb_t** colors;

void addColor(size_t i, int r, int g, int b) {
    rgb_t* color;
    if (i >= COLORCOUNT) {
        // new memory wont be NULL
        colors = realloc(colors, sizeof(rgb_t*) * i);
       //something messy like this...
        //memset(colors[COLORCOUNT-1],0 ,sizeof(rgb_t*) * (i - COLORCOUNT - 1));

         // ...or just do this (EDIT)
        for (j=COLORCOUNT; j<i; j++) {
            colors[j] = NULL;
        }

        COLORCOUNT = i;
    }

    color = malloc(sizeof(rgb_t));
    color->r = r;
    color->g = g;
    color->b = b;

    colors[i] = color;
}

void freeColors() {
    size_t i;
    for (i=0; i<COLORCOUNT; i++) {
        printf("%x\n", colors[i]);
        // can't do this if memory isn't NULL
       // if (colors[i])
         //   free(colors[i]);

    }
}


int main() {
    colors = malloc(sizeof(rgb_t*) * COLORCOUNT);
    memset(colors,0,sizeof(rgb_t*) * COLORCOUNT);
    addColor(0, 255, 0, 0);
    addColor(3, 255, 255, 0);
    addColor(7, 0, 255, 0);


    freeColors();
    getchar();
}
#包括
#包括
#包括
#包括
大小\u t颜色计数=4;
类型定义结构rgb_t{
INTR;
int g;
int b;
}rgb_t;
rgb_t**颜色;
void addColor(大小i、整数r、整数g、整数b){
rgb_t*颜色;
如果(i>=颜色计数){
//新内存不会为空
颜色=realloc(颜色、大小(rgb_t*)*i);
//像这样乱七八糟的东西。。。
//memset(colors[COLORCOUNT-1],0,sizeof(rgb_t*)*(i-COLORCOUNT-1));
//…或仅执行此操作(编辑)
对于(j=颜色计数;jr=r;
颜色->g=g;
颜色->b=b;
颜色[i]=颜色;
}
void freeColors(){
尺寸i;

对于(i=0;i首先,reallocz可能会失败,因此您需要检查NULL。其次,没有更好的方法将内存归零:只需将memset从旧缓冲区的末尾设置到较大缓冲区的末尾。

编写您自己的函数,例如
reallocz
,该函数接受当前大小作为参数,并调用
realloc
>memset
为您提供。它真的不会比您现有的好多少…毕竟是C。

没有办法将此作为一种通用模式来解决。原因是为了知道缓冲区的哪一部分是新的,您需要知道旧缓冲区有多长。在C中无法确定这一点,因此无法防止出现错误l溶液

然而,你可以这样写一个包装器

void* realloc_zero(void* pBuffer, size_t oldSize, size_t newSize) {
  void* pNew = realloc(pBuffer, newSize);
  if ( newSize > oldSize && pNew ) {
    size_t diff = newSize - oldSize;
    void* pStart = ((char*)pNew) + oldSize;
    memset(pStart, 0, diff);
  }
  return pNew;
}

可能不需要执行
memset
:您可能没有使用
colors[k]
,然后再使用有效的设置。例如,您的代码将
colors[i]
设置为新分配的
color
指针,因此不需要将
colors[i]
设置为
NULL

但是,即使您希望“将其归零,这样一切都很好”,或者确实需要新指针为
NULL
:C标准并不保证所有位零都是NULL指针常量(即
NULL
),因此
memset()
无论如何都不是正确的解决方案

唯一可移植的方法是在循环中将每个指针设置为
NULL

size_t k;
for (k=COLORCOUNT; k < i+1; ++k) /* see below for why i+1 */
    colors[k] = NULL;
如果您确实想知道
memset()
调用应该是什么,则需要将从
colors+COLORCOUNT
开始的内存设置为零,并将
i+1-COLORCOUNT
成员设置为零:

memset(colors+COLORCOUNT, 0, (i+1-COLORCOUNT) * sizeof *colors);

但正如我上面所说的,所有字节零都不能保证是
NULL
指针,所以你的
memset()
无论如何都是无用的。如果你想要
NULL
指针,就必须使用循环。

我的注释掉部分使visual studio崩溃,出现了“msvcr90d.dll!memset!”(unsigned char*dst=0x00000000,unsigned char value='',unsigned long count=2553828)第103行Asm“。我刚刚被1打掉了吗?看起来你在颜色[COLORCOUNT-1]处传递了值要重新分配,而不是指向该位置的指针。realloc可能无法重新分配到位,并将返回一个新指针。您应该对此进行检查,如果新值不为空,则使用新值更新颜色。这是代码可能失败的一个原因。另一个原因可能是realloc无法分配更多内存(它返回NULL来告诉您这一点,但您放弃了它)所有字节零点可能是或可能不是空指针常数。详见我的答案。当一个颜色添加到颜色列表的末尾时,这是非常差的性能,通常是调用模式。在重新分配之前,每次只添加一个元素。考虑至少分配MAX(I+ 1,COLCOUNT * 2)。。这只是一个说明问题的示例。实际源是一个按素数IIRCThank调整大小的哈希表-快速编写测试时,realloc错误是一个疏忽,但我没有意识到所有字节为零并不保证按照标准将所有数组成员设为NULL。假设NULL==0是“无意义的”有点言过其实。即使标准没有明确要求,但我知道每个已知的C编译器都是如此。此外,使用calloc或memset强制错误读取可以显著加快错误消除。我宁愿通过
assert(NULL==0)强制NULL==0
在程序开始时,要编写大量复杂而奇怪的代码来支持一个选择其他内容的随机实现。@DanBechard
NULL==0
总是正确的。因此,您必须执行
断言
类似这样的操作:
void*NULL\u ptr=NULL;unsigned char*NULL\u ptr\u byte=&NULL\ptr;对于(size_t i=0;i
-oh,您不能只做
memset(&null_ptr,0,sizeof(null_ptr));assert(!null_ptr);
因为所有位零根本不需要是有效的指针表示,但可能是陷阱表示或导致未定义的行为,这是您首先要防止的-基本上使您的断言无效。@Bodotheisen如果您可以保证
NULL==0
始终为真,您就不需要这样做不要插入任何内容。这就是问题所在!@DanBechard“值为0的整数常量表达式,或转换为void*类型的表达式,称为空指针常量。66)如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与指向任何对象或函数的指针相比不相等。”脚注:“66)宏空在(和其他标题)中定义为空指针常量;请参见ISO C标准(ISO/IEC 9899:2011)第55页的7.19。”6.3.2.3(3)这里讨论的问题是位表示不需要为零。
memset(colors+COLORCOUNT, 0, (i+1-COLORCOUNT) * sizeof *colors);