1

我有一个函数,我将一个数组传递给我的主函数,并将一个 int 传递给我的主函数。我正在对这个新函数中的数组进行操作,我们称之为 foo。在 foo 中,我用 0 初始化另一个包含 52 个单元格的数组。我对从 main 传递的数组执行操作,并将该数据传输到新初始化的数组。我想将新数组返回给主函数。但当然,我不能返回像数组这样的数据结构。所以我改为返回一个指向该数组的 int 指针。在 int main 内部,我传递指针以使其指向数组中的各个单元格。当我打印指针指向的结果时,它应该指向 0 或大于 0 的整数。但是,我得到的结果不一致。出于某种原因,一些应该为 0 的值会打印出垃圾数据。我' 一段时间以来一直试图发现这个错误,但我只是想看看它。无论如何,这只是这部分代码的一般想法......

int main(){
    int *retPtr;
    char input[] = "abaecedg";
    retPtr = foo(input, size);
    for(i=0; i<52; i++){
        // error displayed here
        printf("%d\n", *(retPr + i));
    }
}

int foo(char input[], int size)
{
    int arr[52] = {0};      // should initialize all 52 cells with 0.
    int i=0, value;         // looking for non-zero results in the end.        
    int *ptr = &arr[0];                        
    for(i=0; i<size; i++){
        if(arr[i] > 64 && arr[i] < 91){
            value = input[i] - 65;
            arr[value]++;
        }
    }
    return ptr;
}

希望这对我正在尝试做的事情有意义。在 foo 函数中,我试图找到某些字母的频率。我知道这可能有点神秘,但是代码很长,带有注释和所有内容,所以我想让它尽可能简洁。有什么可能的原因让我得到一些(数字> 0、0)的正确值和另一个垃圾值?

4

2 回答 2

6

你得到垃圾的原因是创建的数组foo是在 foos 堆栈帧中分配的,然后你返回一个指向该帧的指针。返回时丢弃该帧foo

如果您希望它在foo返回后保留,您应该在堆上分配数组(使用 malloc 和朋友)。free()完成数组后不要忘记它。

int main(){
    char input[] = "abaecedg";
    int retPtr[] = foo(input, size); //An array and a pointer is the same thing
    ...
    free(retPtr);
}

int *foo(char input[], int size)
{
    int arr[] = calloc(52*sizeof(int); // should initialize all 52 cells with 0.
    ...
    arr[value]++;
    ...
    return arr;
}

另一种方法是让foo数组作为参数并使用它,以这种方式:

int main(){
    int ret[52] = {0};
    ...
    foo(input, size, ret);
    ...
}

void foo(char input[], int size, int *arr)
{
    ...
    arr[value]++;
    ...
    return; //Don't return anything, you have changed the array in-place
}

之所以可行,是因为数组与指针完全相同,因此您实际上是通过引用将数组传递到foo. arr将指向同一个地方ret,进入堆栈帧main

于 2012-12-02T07:27:00.697 回答
1

在函数foo中,数组arr是一个本地数组,即分配在栈上。您不能返回任何分配在堆栈上的数据指针,因为从函数返回后堆栈会回退,并且不再需要保证其内容。

如果你想返回一个数组,你应该在堆上分配它malloc,例如,并返回返回的指针malloc。但是您将不得不free在程序中的某个地方保留该内存。如果您未能释放它,您将遇到所谓的“内存泄漏”,这可能会或可能不会崩溃/干扰该程序再次运行,具体取决于您的环境。一个不干净的情况,这是肯定的。

这就是为什么我认为 C 对于函数式编程习惯用法不太好,例如从函数返回东西(除非它们是原始类型)。我将通过将另一个数组传递给 foo 来实现您尝试做的事情 - 一个输出数组,伴随着一个大小变量,并填充该数组。

或者,您可以将数组包装在一个结构中并返回该结构。结构可以按值返回,在这种情况下,它们通过堆栈复制到调用函数的返回值。

于 2012-12-02T07:35:24.227 回答