【问题标题】:Why can't I use a function parameter as an array size in C? [duplicate]为什么我不能在 C 中使用函数参数作为数组大小? [复制]
【发布时间】:2017-11-11 02:31:04
【问题描述】:

我正在尝试创建一个简单的数组扩展函数,该函数创建一个新数组,其值与前一个数组相同,但扩展了一个值:

char* test(char array[], int expandBy) {
    char newArray[sizeof(array) + expandBy];
    strncpy(newArray, array, sizeof(array));

    return newArray;
}

但是,我收到了编译时错误expression must have a constant value。我看到的所有类似问题的答案都建议使用宏,但如果我事先不知道值,我就不能使用宏。

有谁知道我该如何解决这个问题,或者是否有替代方法?

【问题讨论】:

  • 你有一个比编译器错误更严重的问题:你返回一个指向局部变量的指针。一旦函数返回,局部变量就会超出范围,这会给您留下一个指向不再存在的数组的流浪指针。尝试取消引用返回的指针将导致 undefined behavior
  • 在另一个不相关的注释中,有strncpy 不会添加终止符的情况。请注意这一点。
  • 一旦将数组传递给函数,它就会衰减为指针。此时 sizeof 告诉您指针的大小,而不是数组的长度。如果它是一个以空结尾的字符串,您可以使用 strlen 来查找内容的长度,但这可能不是实际数组的长度。 stackoverflow.com/questions/492384/…
  • @Someprogrammerdude:实际上重要的是newArray 对象的生命周期,而不是其名称的范围。范围是其中 name 可见。生命周期是一个对象存在时。
  • 顺便说一句,我怀疑 OP 没有用现代标准 C 版本编译它。我在他们的代码中没有看到任何会产生关于常量值的错误的表达式。但是,如果他们使用不支持可变长度数组的 C 版本,他们会在 newArray 声明中收到该错误,因为它使用维度的运行时值。所以 OP 得到错误的原因实际上与 sizeof(array) 不产生“数组”的大小这一事实无关。

标签: c arrays strncpy


【解决方案1】:

这是因为将数组传递给函数实际上是传递一个指针,所以sizeof给你的是指针的大小而不是数组的大小,一个简单的解决方案是

char *test(char *array, size_t current_size, size_t expand_size)
{
    char string[current_size + expand_size + 1];
    // Rest of your code
}

但是,从这个函数返回数组string 是错误的,因为它只在函数内有效。

我认为在继续使用 c 编码之前,您需要阅读有关内存分配、数组和指针的内容,因为很明显您还没有所需的知识。

此外,通常您应该避免使用strncpy(),因为该函数不能保证null 终止符,结果很容易得到一个非null 终止的数组,您将假设为一个字符串,但它当然不是。

【讨论】:

    【解决方案2】:

    我在您的代码中发现两个错误。

    首先,将数组传递给函数就是将指针传递给数组中的第一个元素。所以sizeof(array)返回的是指针的大小,而不是整个数组。

    其次,函数中的数组存放在栈中,程序离开函数后会被销毁。返回由char newArray[size] 创建的数组时,除了错误之外什么都得不到。

    这是我的代码,可能会对您有所帮助:

    #include <stdlib.h>
    #include <string.h>
    
    char *NewArray(char arr[], int arr_size, int expand_size)
    {
        int new_size = arr_size + expand_size;
        char *new_arr = malloc(sizeof(char) * new_size);
        strncpy(new_arr, arr, new_size * sizeof(char));
    
        return new_arr;
    }
    

    【讨论】:

    • 一个小提示:您使用sizeof(char) * new_size 来计算传递给malloc 的大小,但只使用new_size 来计算传递给strncpy 的大小。当然,它们与char 相同,但在两个地方使用相同的样式可能会很好——要么使用sizeof(char) * new_size 使尺寸明确和突出,以防类型发生变化,或者使用new_size为简洁起见,在这两个地方。或者可能是sizeof *arr * new_size,因此如果数组类型发生更改,大小会自动更改。
    • "返回由char newArray[size]创建的数组时,除了错误之外什么也得不到" 是的,但是OP没有这样做,所以为什么要提到它?
    猜你喜欢
    • 2014-11-23
    • 1970-01-01
    • 2020-04-10
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多