在C函数中分配和访问数组

brccelvz  于 2023-01-16  发布在  其他
关注(0)|答案(3)|浏览(125)

我写了一个函数来为数组分配内存,并将数组长度存储在一个指针中,这样我就可以在主函数中使用这两个函数了。一切似乎都很好,直到我试图循环通过数组打印值。
当我使用数组大小指针来终止打印循环时,它表现出奇怪的行为。你能告诉我哪里出错了吗?
提前感谢:)

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

void func (int** arr, int** len){

    int length = 5;
    *len=&length;

    *arr = malloc(sizeof(int)*(**len));

    for (int i=0; i<(**len); ++i){
        (*arr)[i]=i*10;
    }    
}

int main(){

    int* len = NULL;
    int* arr = NULL;

    func(&arr, &len);

    for (int i=0; i<5; ++i){
        printf("%d\n", arr[i]);
    } //works
    /*
    for (int i=0; i<*len; ++i){
        printf("%d\n", arr[i]);
    } //doesnt work
    */

    free(arr);

    return 0;
}
hiz5n14c

hiz5n14c1#

int length = 5;
*len=&length;

这里赋值*len指向一个局部变量(length),当函数返回时,局部变量length将超出作用域,之后取消引用指针将有未定义的行为。
如果您在main中为int分配内存,并将指向该内存的指针提供给func,您将获得正确的行为。

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

void func(int** arr, int* len) { // int* instead
    int length = 5;
    *len = length;

    *arr = malloc(length * sizeof **arr);

    for (int i = 0; i < length; ++i) {
        (*arr)[i] = i * 10;
    }
}

int main() {
    int len;               // automatic storage
    int* arr = NULL;

    func(&arr, &len);

    for (int i = 0; i < len; ++i) {
        printf("%d\n", arr[i]);
    }  // now works

    free(arr);
}
enyaitl3

enyaitl32#

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

上面的代码不起作用,因为len的内容不确定。
*与不确定或NULL指针一起使用会产生未定义的行为。*

    • 如果一个对象在其生存期之外被引用,则该行为是未定义的。当指针所指向(或刚刚过去)的对象到达其生存期结束时,指针的值将变得不确定。¹*

在函数func中,lenght是一个局部变量,一旦函数返回,它就会被销毁。

    • 对象的生存期是程序执行的一部分,在此期间,存储空间被保证为它保留。对象存在,有一个恒定的地址,并在其整个生存期内保留它最后存储的值。²*
    • 对于这样一个没有可变长度数组类型的对象,它的生存期从进入与之关联的块开始一直延续到该块的执行以任何方式结束。

由于lenght在编译时是已知的,并且永远不会更改,因此不需要传递指向int的指针,只需传递一个int进行分配即可。

  • [1]、[2]、[3] - C11,6.2.4对象的存储期限。*
4szc88ey

4szc88ey3#

你应该已经正确地使用了指针。你传递了一个指向函数指针的指针,并且你试图向指针写入一个值。

int a = 0;
fun(&a);
{
*a = 42;
}
#include <stdio.h>
#include <stdlib.h>

void func (int** arr, int* len){

    int length = 5;
    *len=length;

    *arr = malloc(sizeof(int)*(*len));

    for (int i=0; i<(*len); ++i)
    {
        (*arr)[i]=i*10;
    }    
}

int main(){

    int len = 0;
    int* arr = NULL;

    func(&arr, &len);

    for (int i=0; i<5; ++i){
        printf("%d\n", arr[i]);
    } //works
    
    for (int i=0; i<len; ++i){
        printf("%d\n", arr[i]);
    } //doesnt work
    

    free(arr);

    return 0;
}

相关问题