重新分配后如何将新内存清零 [英] How to zero out new memory after realloc
问题描述
在调用 realloc 后将新内存归零同时保持初始分配的内存完好无损的最佳方法是什么?
What is the best way to zero out new memory after calling realloc while keeping the initially allocated memory intact?
#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
", 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();
}
推荐答案
可能不需要做 memset
:你可能没有使用 colors[k]
在用一些有效的东西设置它之前.例如,您的代码将 colors[i]
设置为新分配的 color
指针,因此您无需设置 colors[i]
到 NULL
.
There is probably no need to do the memset
: you may not be using colors[k]
before setting it with something valid later. For example, your code sets colors[i]
to a newly allocated color
pointer, so you didn't need to set colors[i]
to NULL
.
但是,即使您想将其归零以便一切顺利",或者确实需要将新指针设为 NULL
:C 标准并不保证所有位为零是空指针常量(即 NULL
),所以 memset()
无论如何都不是正确的解决方案.
But, even if you wanted to "zero it out so everything is nice", or really need the new pointers to be NULL
: the C standard doesn't guarantee that all-bits-zero is the null pointer constant (i.e., NULL
), so memset()
isn't the right solution anyway.
你能做的唯一可移植的事情是在循环中将每个指针设置为NULL
:
The only portable thing you can do is to set each pointer to NULL
in a loop:
size_t k;
for (k=COLORCOUNT; k < i+1; ++k) /* see below for why i+1 */
colors[k] = NULL;
您的主要问题是您的 realloc()
调用是错误的.realloc()
返回一个指向调整大小的内存的指针,它不会(必须)就地调整大小.
Your primary problem is that your realloc()
call is wrong. realloc()
returns a pointer to the resized memory, it doesn't (necessarily) resize it in-place.
所以,你应该这样做:
/* 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 */
}
如果你真的想知道 memset()
调用应该是什么,你需要将 colors+COLORCOUNT
开始的内存设置为零,并设置 i+1-COLORCOUNT
个成员归零:
If you really want to know what the memset()
call should be, you need to set to zero the memory starting at colors+COLORCOUNT
, and set i+1-COLORCOUNT
members to zero:
memset(colors+COLORCOUNT, 0, (i+1-COLORCOUNT) * sizeof *colors);
但正如我上面所说的,不能保证所有零字节都是 NULL
指针,所以你的 memset()
无论如何都没用.如果你想要 NULL
指针,你必须使用循环.
But as I said above, all bytes zero is not guaranteed to be a NULL
pointer, so your memset()
is useless anyway. You have to use a loop if you want NULL
pointers.
这篇关于重新分配后如何将新内存清零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!