【问题标题】:How to properly access this realloc-ed array?如何正确访问这个重新分配的数组?
【发布时间】:2022-01-11 00:59:35
【问题描述】:

在下面的这段代码中,我试图创建一个可以从main() 函数访问的整数数组,但是,Address-sanitizer 给了我堆栈缓冲区溢出错误,我无法弄清楚我在做什么错误的。我错过了什么?

#include <stdlib.h>

void reallocFail(int **arrayOfInts) {
    *arrayOfInts = (int *)malloc(sizeof(int));
    for (int i = 1; i <= 10; i++) {
        *arrayOfInts = (int *)realloc(*arrayOfInts, (i) * sizeof(int));
        *arrayOfInts[i - 1] = i;
    }
}

int main(void) {
    int *arrayOfInts;
    reallocFail(&arrayOfInts);
    return 0;
}

【问题讨论】:

  • 谢谢,我在这上面浪费了太多时间

标签: c dynamic-memory-allocation realloc function-definition


【解决方案1】:

对于初学者来说,在 for 循环之前分配内存

*arrayOfInts = (int*)malloc(sizeof(int));

是多余的。你可以写

*arrayOfInts = NULL;

还要检查内存分配是否成功。

还有这条记录

    *arrayOfInts[i-1] = i;

等价于

    *( arrayOfInts[i-1] ) = i;

但你需要

    ( *arrayOfInts )[i-1] = i;

函数可以如下所示

size_t reallocFail( int **arrayOfInts, size_t n )
{
    *arrayOfInts = NULL;
    size_t i = 0;

    if ( n != 0 )
    {
        int *tmp = NULL;

        do
        {
            tmp = realloc( *arrayOfInts, ( i + 1 ) * sizeof( int ) );

            if ( tmp != NULL )
            {
                tmp[i]  = i + 1;
                *arrayOfInts = tmp;
            }
        } while ( tmp != NULL && ++i != n );
    }

    return i;
}

并且可以像这样调用该函数

int *arrayOfInts = NULL;

size_t n = reallocFail( &arrayOfInts, 10 );

for ( size_t i = 0; i != n; i++ )
{
    printf( "%d ", arrayOfInts[i] );
}

putchar( '\n' );

free( arrayOfInts ); 

这是一个演示程序。

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

size_t reallocFail( int **arrayOfInts, size_t n )
{
    *arrayOfInts = NULL;
    size_t i = 0;

    if ( n != 0 )
    {
        int *tmp = NULL;

        do
        {
            tmp = realloc( *arrayOfInts, ( i + 1 ) * sizeof( int ) );

            if ( tmp != NULL )
            {
                tmp[i]  = i + 1;
                *arrayOfInts = tmp;
            }
        } while ( tmp != NULL && ++i != n );
    }

    return i;
}

int main( void ) 
{
    int *arrayOfInts = NULL;

    size_t n = reallocFail( &arrayOfInts, 10 );

    for ( size_t i = 0; i != n; i++ )
    {
        printf( "%d ", arrayOfInts[i] );
    }

    putchar( '\n' );

    free( arrayOfInts );

    return 0;
}

程序输出是

1 2 3 4 5 6 7 8 9 10 

当然,在函数内的循环中重新分配内存没有太大意义。该函数只是演示了如何管理函数realloc

【讨论】:

    【解决方案2】:

    *arrayOfInts[i - 1] = i; 中只有一个简单的错字。后缀运算符如[] 比前缀运算符如* 绑定更强。因此你应该写:

       (*arrayOfInts)[i - 1] = i;
    

    还请注意,您应该检查内存重新分配失败,您可以将*arrayOfInts 初始化为NULL,因为realloc(NULL, size) 等效于malloc(size)

    这是修改后的版本:

    #include <string.h>
    #include <stdlib.h>
    
    int reallocFail(int **pp, int n) {
        int i;
        *pp = NULL;
        for (i = 0; i < n; i++) {
            int *p = realloc(*pp, (i + 1) * sizeof(*p));
            if (p == NULL)
                break;
            p[i] = i + 1;
            *pp = p;
        }
        return i;
    }
    
    int main(void) {
        int *arrayOfInts = NULL;
        int n = reallocFail(&arrayOfInts, 10);
        for (int i = 0; i < n; i++) {
            printf("%d%c", arrayOfInts[i], " \n"[i == n-1]);
        }
        free(arrayOfInt);
        return 0;
    }
    

    【讨论】:

      【解决方案3】:
      void reallocFail(int **arrayOfInts) 
      {
          for (int i = 1; i <= 10; i++) 
          {
              *arrayOfInts = realloc(*arrayOfInts, i * sizeof(**arrayOfInts));
              arrayOfInts[0][i - 1] = i;
          }
      }
      
      int main(void) {
          int *arrayOfInts = NULL;
          reallocFail(&arrayOfInts);
          return 0;
      }
      

      但是这段代码可以简化为一个realloc(我知道你测试了realloc是否有效)。 IT 不会检查realloc 是成功还是失败:

      void reallocFail(int **arrayOfInts) 
      {
          int *tmp;
          for (int i = 1; i <= 10; i++) 
          {
              tmp = realloc(*arrayOfInts, i * sizeof(**arrayOfInts));
              if(tmp)
              {
                  *arrayOfInts = tmp;
                  arrayOfInts[0][i - 1] = i;
              }
              else
                  printf("Alloction error\n");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-03-11
        • 2020-07-07
        • 1970-01-01
        • 2013-11-30
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 1970-01-01
        • 2020-08-15
        相关资源
        最近更新 更多