【问题标题】:Segfault and uninitialized data when generating a random array in C [duplicate]在C中生成随机数组时的段错误和未初始化的数据[重复]
【发布时间】:2018-08-29 07:51:51
【问题描述】:
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#define len 10

int *randomArray(void);

int main()
{
    srand(time(NULL));
    int *rArray = (int *)malloc(sizeof(int) * len);
    rArray = randomArray();
    for (int i = 0; i < len; i++) {
        printf("%d ", *(rArray+i));
    }
    puts("");
    free(rArray);
}

int *randomArray(void)
{
    int array[len] = { 0 };
    for (int i = 0; i < len; i++) {
        array[i] = rand() % len;
    }
    return array;
}

任务是创建一个ints 的数组,并让一个函数用随机数填充该数组。函数randomArray() 工作得很好,但由于某种原因,赋值rArray = randomArray() 不能正常工作,尽管rArray 的某些元素是有效数字而不是乱码。此外,最后一条主线free(rArray); 使程序崩溃,这让我感到麻木,这没有任何意义。如果我删除该行,程序不会崩溃,但我们都知道您需要 free() 一个 malloc()-ed 数组。

【问题讨论】:

    标签: c arrays segmentation-fault


    【解决方案1】:

    这里的主要问题是,arrayrandomArray() 函数范围内的局部变量。一旦函数返回,返回的地址就变为无效。任何进一步使用内存的尝试都将导致undefined behavior

    此外,根据您的方法,您试图通过函数调用返回的地址覆盖分配的内存,这将导致内存泄漏。相反,更改您的设计,将分配的内存作为参数传递给函数,然后使用 rand() 调用填充元素。

    【讨论】:

      【解决方案2】:

      randomArray 返回一个指向本地数组 array 的第一个元素的指针。

      一旦函数返回,因为变量超出范围,该指针立即变为无效。以任何方式使用它都会导致undefined behavior

      更糟糕的是你重新分配指针rArray,使你失去了原来分配的内存。这意味着您拨打free再次将导致UB。

      要解决这两个问题,请将指针和大小作为参数传递给randomArray 函数:

      void randomArray(int *array, int size)
      {
          for (int i = 0; i < size; ++i)
          {
              array[i] = rand() % size;
          }
      }
      

      【讨论】:

      • 是的,但在这种情况下,传递大小将是多余的,因为它已经被定义为宏。只是说。
      • @SouravGhosh 当传递一个指向“数组”的指针时,传递它的大小总是一个好习惯。大小可能并不总是可用作宏。 :)
      【解决方案3】:
      int *randomArray(void)
      {
          int array[len] = { 0 };
          //...
          return array;
       }
      

      array 超出} 的范围,访问这个返回的指针是 UB。 此外,rArray = randomArray(); 会泄漏内存,因为现在您无法释放 malloc 的内存。您应该将rArray 传递给一个函数,该函数将负责归档它。

      【讨论】:

        【解决方案4】:

        在 randomArray() 函数中,您将返回分配在堆栈上的数组。从 randomArray() 函数返回时,该数组将被释放。相反,您可以这样做:

        void randomArray(int * array)
        {
            // Remove this int array[len] = { 0 };
            for (int i = 0; i < len; i++) {
                array[i] = rand() % len;
            }
            // Remove this .. return array;
        }
        

        并从 main() 调用 randomArray(rArray)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-09-24
          • 1970-01-01
          • 2018-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-10
          相关资源
          最近更新 更多