【问题标题】:Weird issue when making an array of random ints in C在 C 中制作随机整数数组时的奇怪问题
【发布时间】:2021-05-16 08:59:06
【问题描述】:

我目前正在学习 C,我需要编写一个函数来创建一个随机整数数组。我遇到了一个问题,在创建后我尝试正确打印前 8 个数字,但其余数字不正确。

int* create(int n) {
    int* array = malloc(n);
    if (!array) return NULL;
    srand(time(NULL));
    for (int i = 0; i < n; i++) {
        array[i] = rand() % 100 + 1;
        printf("num: %i\n", array[i]);
    }

    for (int i = 0; i < n; i++) {
        printf("%i\n", array[i]);
    }

    return array;
}

这是我的输出:

num: 39
num: 2
num: 15
num: 74
num: 80
num: 29
num: 14
num: 16
num: 8
num: 11
num: 2
39
2
15
74
80
29
14
16
973747761
909588276
2614

【问题讨论】:

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


    【解决方案1】:

    这个内存分配

    int* array = malloc(n);
    

    n 类型为 int 的元素的数组分配的内存不足,您必须编写

    int* array = malloc( n * sizeof( int ) );
    

    参数也应该是无符号整数类型。否则用户可以传递一个负整数,这将导致未定义的行为。

    最好将参数声明为具有size_t 类型。是函数malloc的参数类型。

    函数应该做一件事:分配和初始化一个数组。如果函数没有返回空指针,则由函数的调用者决定是否输出数组。

    所以函数看起来像

    int * create( size_t n ) 
    {
        const int MAX_VALUE = 100;
    
        int *array = malloc( n * sizeof( int ) );
    
        if ( array != NULL )
        { 
            srand( ( unsigned int )time( NULL ) );
    
            for ( size_t i = 0; i < n; i++ )  
            {
                array[i] = rand() % MAX_VALUE + 1;
            }
        }
    
        return array;
    }
    

    这是一个演示程序。

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int * create( size_t n ) 
    {
        const int MAX_VALUE = 100;
    
        int *array = malloc( n * sizeof( int ) );
    
        if ( array != NULL )
        { 
            srand( ( unsigned int )time( NULL ) );
    
            for ( size_t i = 0; i < n; i++ )  
            {
                array[i] = rand() % MAX_VALUE + 1;
            }
        }
    
        return array;
    }
    
    int main(void) 
    {
        size_t n = 0;
        
        printf( "Enter the size of an array: " );
        
        scanf( "%zu", &n );
        
        int *array = create( n );
        
        if ( array != NULL )
        {
            for ( size_t i = 0; i < n; i++ )
            {
                printf( "%d ", array[i] );
            }
            
            putchar( '\n' );
        }
        
        free( array );
        
        return 0;
    }
    

    它的输出可能看起来像

    Enter the size of an array: 10
    75 36 30 75 53 49 42 52 61 9 
    

    虽然最好以用户可以自己确定最大值的方式声明函数。那就是函数看起来像

    int * create( size_t n, int max_value ) 
    {
        int *array = malloc( n * sizeof( int ) );
    
        if ( array != NULL )
        { 
            srand( ( unsigned int )time( NULL ) );
    
            for ( size_t i = 0; i < n; i++ )  
            {
                array[i] = rand() % max_value + 1;
            }
        }
    
        return array;
    }
    

    【讨论】:

      【解决方案2】:

      您的代码存在问题: malloc 需要 size_t,您直接给出 int。所以你应该在技术上这样做:

          int *array = malloc(sizeof(int) * n);
      

      这基本上说分配nsizeof(int) 每个字节。 您正在做的是分配 n 字节的数据。该程序不能保证始终运行,并且您已超出范围。如果幸运的话,您会在其中一次运行中获得Segmentation Fault

      【讨论】:

      • int 提供malloc 参数本质上不是问题。参数将自动转换。如果它溢出了int 范围,那将是一个问题。
      • @EricPostpischil 啊,是的。编译器只会将int 隐式类型转换为size_t。但要注意负的int(例如:malloc(-1) 将导致整数溢出,并在具有非常基本内存分配器的操作系统上分配几乎所有内存)。
      【解决方案3】:

      您没有分配足够的空间。 malloc(n) 分配 n 字节。您需要n ints 的空间!改用malloc(n * sizeof(int)),或者更好的是:malloc(n * sizeof(*array))(这样你就不需要重复输入了)。

      【讨论】:

        猜你喜欢
        • 2014-03-03
        • 1970-01-01
        • 2018-05-11
        • 1970-01-01
        • 2013-04-28
        • 2012-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多