我有一个动态的二维数组,大小是高度*宽度。
我想使用realloc更改数组大小。
这是我的代码,但它无效。
我该怎么办?帮帮我!!
int main(){
char **img;
img = (char**)malloc(sizeof(char*)*height);
for(i=0;i<height;i++){
img[i] = (char*) malloc(sizeof(char)*width);
}
resize(height*2, width*2, img);
}
void resize(int height, int width, char **img){
int i;
img = (char**)realloc(img, sizeof(char)*height);
for(i=0;i<h;i++){
img[i] = (char*)realloc(img[i], width);
}
}
答案 0 :(得分:0)
除了你
void
- 指针
int
应为size_t
s 这里有两个主要的错误,如代码
height
乘以sizeof (char)
而不是sizeof (char*)
。realloc
。带有NULL
的数组,然后通过内部调整大小循环将它们传递给realloc()
。因此,假设新高度大于或等于旧高度的最小调整可能看起来像
void resize(size_t height, size_t height_current, size_t width, char **img){
int i;
img = (char**)realloc(img, sizeof(char*)*height);
for(i=height_current;i<height;i++){
img[i] = NULL;
}
for(i=0;i<width;i++){ // correct copypasta mistake here
img[i] = (char*)realloc(img[i], width);
}
}
更好的版本可能看起来像这样
void resize(size_t height, size_t height_current, size_t width, size_t char **img)
{
if (height != height_current)
{
if (height < height_current)
{
for (size_t i = height; i < height_current; ++i)
{
free(img[i]);
}
}
img = realloc(img, height * sizeof *img);
if (height > height_current)
{
for (size_t i = height_current; i < height; ++i)
{
img[i] = NULL;
}
}
}
for (size_t i = 0; i < width; ++i)
{
img[i] = realloc(img[i], width * sizeof *img[i]);
}
}
这样称呼:
resize(height*2, height, width*2, img);
此外,您确实想要对所有对malloc()
和realloc()
的调用添加错误检查,因为它们可能会失败!
答案 1 :(得分:0)
有两个主要问题。首先,realloc
可以将内存块移动到新位置。因此realloc
的返回值指向&#34; old&#34;如果不需要移动,则为内存块;如果需要移动,则为新块;如果发生错误,则为NULL。然而你忽略了resize
中的这个事实,因为它无法改变调用者传入的指针对象。我建议调整原型使resize
返回一个(可能是新的)指针就像realloc
确实如此。
其次,在重新分配每一行时,数组中可能存在未初始化的值,可能指向&#34;某处&#34;。重新分配这样一个未初始化的值是未定义的行为。我建议设置&#34; new&#34;行NULL
使得realloc
之后可以正常行为。因此有必要知道&#34; old&#34;高度,因为你没有机会区分定期初始化的指针和&#34;垃圾&#34;指针。
参见改编的代码。希望它有所帮助。
char** resize(int oldHeight, int oldWidth, int height, int width, char **img){
int i;
img = realloc(img, sizeof(char)*height);
for (int i=oldHeight; i<height; i++)
img[i] = NULL;
for(i=0;i<height;i++){
img[i] = realloc(img[i], width);
for (int col=oldWidth; col < width; col++) {
img[i][col] = 0;
}
}
return img;
}
int main(){
int height = 10;
int width = 20;
char **img;
img = malloc(sizeof(char*)*height);
for(int i=0;i<height;i++){
img[i] = malloc(sizeof(char)*width);
}
img = resize(height, width, height*2, width*2, img);
}
答案 2 :(得分:0)
要正确执行此操作,必须在调整大小之前至少知道行数。一种可能性是定义包含附加信息的struct
(一种OOP方法,将所有相关数据放在一起),如下例所示(也存储列数,仅用于完整性,未经测试的代码):
#include <stdlib.h>
#include <string.h>
typedef struct Lookup Lookup;
struct Lookup
{
size_t rows;
size_t cols;
char **data;
};
static void Lookup_destroy(Lookup *self)
{
if (!self) return;
for (size_t r = 0; r < self->rows; ++r)
{
free(self->data[r]);
}
free(self->data);
free(self);
}
static Lookup *Lookup_create(size_t rows, size_t cols)
{
Lookup *self = malloc(sizeof *self);
if (!self) return 0;
self->rows = rows;
self->cols = cols;
self->data = malloc(rows * sizeof *(self->data));
if (!self->data)
{
free(self);
return 0;
}
memset(self->data, 0, rows * sizeof *(self->data));
for (size_t r = 0; r < rows; ++r)
{
self->data[r] = malloc(cols * sizeof *(self->data[r]));
if (!self->data[r])
{
Lookup_destroy(self);
return 0;
}
}
return self;
}
static Lookup *Lookup_resize(Lookup *self, size_t rows, size_t cols)
{
if (!self) return Lookup_create(rows, cols);
// free rows that are no longer needed, if any:
for (size_t r = rows; r < self->rows; ++r)
{
free(self->data[r]);
self->data[r] = 0;
}
// reallocate array of rows:
char **newdata = realloc(self->data, rows * sizeof *newdata);
if (!newdata)
{
Lookup_destroy(self);
return 0;
}
// update row array and row count:
self->data = newdata;
size_t oldrows = self->rows;
self->rows = rows;
// initialize new rows to NULL, if any:
if (rows > oldrows)
{
memset(self->data + oldrows, 0,
(rows - oldrows) * sizeof *(self->data));
}
// reallocate individual rows:
for (size_t r = 0; r < rows; ++r)
{
char *newrow = realloc(self->data[r], cols * sizeof *newrow);
if (!newrow)
{
Lookup_destroy(self);
return 0;
}
self->data[r] = newrow;
}
// update col count:
self->cols = cols;
return self;
}
请注意realloc()
的结果总是首先存储到临时变量,这是正确处理错误所必需的。如果出现任何错误,此代码会丢弃整个对象 - 当然,您可以使用更多代码执行不同的操作。
您可以在代码中使用它:
int main(){
Lookup img;
img = Lookup_create(height, width);
// check for NULL here
img = Lookup_resize(img, height*2, width*2);
// and check for NULL here
}