代码之家  ›  专栏  ›  技术社区  ›  Nick Van Brunt

如何在realloc之后清空新内存

  •  8
  • Nick Van Brunt  · 技术社区  · 16 年前

    调用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();
    }
    
    4 回复  |  直到 16 年前
        1
  •  4
  •   Alok Singhal    16 年前

    memset colors[k] colors[i] 新分配的 color 指针,所以您不需要设置 颜色[i] NULL .

    但是,即使你想“把它归零,这样一切都好”,或者真的需要新的指针 无效的 无效的 ),所以 memset()

    无效的

    size_t k;
    for (k=COLORCOUNT; k < i+1; ++k) /* see below for why i+1 */
        colors[k] = NULL;
    

    你的主要问题是你的 realloc() 打错电话了。 返回一个指向已调整大小的内存的指针,它不(必须)在适当的位置调整大小。

    /* i+1 because you later assign to colors[i] */
    rgb_t **tmp = realloc(colors, (i+1) * sizeof *tmp);
    if (tmp != NULL) {
        /* realloc succeeded, can't use colors anymore */
        colors = tmp;
    } else {
        /* realloc failed, colors is still valid */
    }
    

    如果你真的想知道 调用应该是,您需要将从开始的内存设置为零 colors+COLORCOUNT ,并设置 i+1-COLORCOUNT 归零的成员:

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

    无效的 指针,所以你的 反正也没用。如果需要,必须使用循环 无效的 指针。

        2
  •  9
  •   JaredPar    16 年前

    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;
    }
    
        3
  •  4
  •   florin    16 年前

    首先,realloc可能会失败,因此需要检查NULL。第二,没有更好的方法将内存归零:只需将memset从旧缓冲区的末尾设置到更大缓冲区的末尾。

        4
  •  2
  •   Thomas    16 年前

    reallocz ,它接受当前大小作为参数,并调用 realloc memset 为你。它真的不会比你已经拥有的更好。。。毕竟是C。