重新分配具有无效下一个大小错误的动态无符号字符数组时出错

Error when reallocating dynamic unsigned char array with invalid next size error

我正在尝试创建一个动态无符号字符数组,每添加一个元素,行数就会增加:

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

#define BLOCKSIZE 1

int main()
{
    unsigned char **p = NULL, rows = 0;
    // initialize p pointer to as the size of one char
    p = malloc ( BLOCKSIZE * sizeof ( unsigned char *) );
    // add 10 "TEST" elements
    for (;rows < 10; rows++ )
    {
        if (rows > BLOCKSIZE) {
            // allocate memory for each row
            p = realloc (p, rows * sizeof ( unsigned char *) );
        }
        // allocate memory for each column
        p[rows] = malloc (rows * sizeof (unsigned char  ));
        // add element
        p[rows] = "TEST";
    }
    for (int i=0; i < rows; i++)
        printf("%s\n", p[i]);

    return 0;
}

代码在 运行:

时输出此错误
realloc(): invalid next size
Aborted (core dumped)

有人可以向我解释我做错了什么吗?

  • realloc调用中:
p = realloc (p, rows * sizeof ( unsigned char *) );

在循环的第一次迭代中rows为0,分配0字节使得第一行无法保存赋值,并且在随后的重新分配中没有足够的space用于您正在分配的指针数量,总是比需要的少一个,这会导致对未分配内存的无效访问。

你至少应该重新分配1的大小unsigned char*,你也可以在块大小中使用指针本身(sizeof *p):

p = realloc (p, (rows + BLOCKSIZE) * sizeof *p);
  • 第二个malloc没有保留足够的space,它至少应该有你分配给它的字符串的大小,加上空终止符的space所以4 + 1.
p[rows] = malloc (5 * sizeof **p);
  • rows 至少应该是 int 类型,理想情况下 size_t,它用于索引数组没有理由是 unsigned char.

  • 实际上,“TEST”的赋值导致内存泄漏,您只是让 p[rows] 指向一个字符串文字而不是先前分配的内存块。你应该使用:

memcpy(p[rows], "TEST", 5);

strcpy 签名 char

固定码(Online):

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

#define BLOCKSIZE 1

int main()
{
    unsigned char **p = NULL;
    size_t rows = 0;
    p = malloc ( BLOCKSIZE * sizeof *p);
    if(p == NULL){        //always check for allocation failure
        return EXIT_FAILURE;
    }
    for (;rows < 10; rows++ )
    {
        if (rows > BLOCKSIZE) {
            p = realloc (p, (rows + BLOCKSIZE) * sizeof *p );
        }
        if(p == NULL){
            return EXIT_FAILURE;
        }
        //in this case the row is always 4 + 1 chars, but you can have different number of chars per row
        p[rows] = malloc (5 * sizeof **p);
        if(p[rows] == NULL){
            return EXIT_FAILURE;
        }    
        memcpy(p[rows], "TEST", 5);
    }
    for (size_t i=0; i < rows; i++)
        printf("%s\n", p[i]);
    return EXIT_SUCCESS;
}

你有一些错误,我会尝试解释它们并修复代码:

unsigned char **p = NULL, rows = 0;

行是 unsigned char 类型。为什么?它需要 size_t 类型(因为稍后我们将在 maloc/realoc 中使用它,最好是 size_t.

for (;rows < 10; rows++ ){
...

所以,我假设您有错字并且您尝试遍历 integer/size_t 数据类型而不是 unsigned char!

void *realloc(void *ptr, size_t size);

The realloc() function shall deallocate the old object pointed to by ptr and return a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values. Upon successful completion, realloc() shall return a pointer to the (possibly moved) allocated space. If size is 0, either: A null pointer shall be returned and errno set to an implementation-defined value.

任何方式假设 rows 是 size_t 类型(在 for 循环内),您需要像这样重新分配: 那么,如何使用 realloc 呢?

unsigned char **p_temp = p;
p_temp = (unsigned char**)realloc(p_temp, (rows + BLOCKSIZE)*sizeof(unsigned char*));
if(p_temp ==NULL){
/*realloc failed but we still have p ! we didnt encounter a memory leak like your code*/
....
}
else{
p = p_temp; /*let p to point to the new allocated buffer */
}
p[rows] = malloc (rows * sizeof (unsigned char  ));

同样的问题!

我怎么不理解你代码中的逻辑?为什么不分配足够的 space 并省略对 realloc() 的调用?