指向整数的指针数组的初始化和增量

时间:2016-04-08 20:50:29

标签: c arrays bash pointers

我在C中编写了以下代码,用于初始化并增加指向int的指针数组。

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

int * arr;

void initArray (int *arr, int size) {
    arr = malloc(sizeof(int)*size);
    for (int i=0; i< size; i++) {
        arr[i]= i;
        printf("%d ", arr[i]);
    }
    printf("\n");
} 

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


void main(){

    initArray(arr, 3);
    incArray(arr, 3);

}

除非我在两个函数中都使用malloc,否则程序(运行时)会出现此错误:

  

运行“/home/ubuntu/workspace/hello-c-world.c”
  0 1 2
  bash:第12行:93714分段错误“$ file.o”$ args
  流程退出代码:139

不确定为什么一旦initArray函数被调用,为什么它需要在递增函数中再次进行内存分配。我假设它将第二个函数的数组视为一个单独的函数,而我想增加initArray函数创建的第一个数组中的值。

我真的很感激被指向正确的方向。

3 个答案:

答案 0 :(得分:2)

你想要这个:

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

void initArray (int **arr, int size) {
    *arr = malloc(sizeof(int)*size);
    for (int i=0; i< size; i++) {
        (*arr)[i]= i;
        printf("%d ", (*arr)[i]);
    }
    printf("\n");
} 

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


void main(){  
    int *arr;  

    initArray(&arr, 3);  // << this will modify arr
    incArray(arr, 3);    
}

答案 1 :(得分:0)

arr中的initArray()隐藏了全局arr,并且arr中对initArray()所做的修改不会对全局arr进行}。然后,您的代码使用(未修改的)全局incArray()调用arr - 它仍然是空指针。当您尝试使用它时,这会给您一个seg错误。它还意味着在函数返回时泄漏内存。

你需要弄清楚你是否想要全局变量 - 我建议删除它。应尽可能避免全局变量。

您需要更改initArray()功能的签名 - 至少有两个选项。

选项1 - 返回指向已分配空间的指针

您可以更改initArray()以返回指向已分配空间的指针。它将具有签名int *initArray(int size),您将其称为:

int *arr = initArray(3);

这会产生:

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

int *initArray(int size)
{
    int *arr = malloc(sizeof(int)*size);
    if (arr != 0)
    {
        for (int i = 0; i < size; i++)
        {
            arr[i] = i;
            printf("%d ", arr[i]);
        }
        printf("\n");
    }
    return arr;
}

void incArray(int *arr, int size)  // Unchanged
{
    for (int i = 0; i < size; i++)
    {
        arr[i] = i+1;
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main(void)
{
    int *arr = initArray(3);
    if (arr != 0)
        incArray(arr, 3);
    return 0;
}

我与0进行比较时,您可能希望与NULL进行比较。请注意,在使用分配的空间之前,代码会仔细检查分配是否成功。

选项2 - 将指针传递给指针

或者,如果您喜欢双指针,则可以将指针传递给指向函数的指针:

void initArray(int **arr, int size)
{
    *arr = malloc(sizeof(int) * size);
    if (*arr != 0)
    {
        for (int i = 0; i < size; i++)
        {
            (*arr)[i] = i;
            printf("%d ", (*arr)[i]);
        }
        printf("\n");
    }
}

// incArray unchanged again

int main(void)
{
    int *arr;
    initArray(&arr, 3);
    if (arr != 0)
        incArray(arr, 3);
    return 0;
}

答案 2 :(得分:0)

在您的代码中,您有两个名称为arr的变量:一个位于全局范围内,另一个位于initArray函数范围内。请查看initArray

中的此说明
arr = malloc(sizeof(int)*size);

由于函数的局部范围在全局的C语言之前被解析,它是函数的arr参数,它将存储分配,而不是全局arr变量。当你什么也没有返回时,这个指针将在你的函数结束时被销毁,你将无法再访问你的分配。因此,全局arr永远不会被修改,其值始终为NULL或未定义的值。

这就是为什么,当你在写这个写作指令时incArray内......

arr[i]= i+1;

...您实际上是在i + 1或未定义的地址中写NULL,这不是您的进程有权写入的地址,从而导致此分段错误。

一个简单的解决方法是返回initArray中的指针并将其存储在全局arr变量中,如下所示:

int * arr;

int* initArray (int size) {
    int* arr = malloc(sizeof(int)*size);
    // ...
    return arr;
} 

void incArray(int *arr, int size) {
    // ...
} 


void main(){
    arr = initArray(3);
    incArray(arr, 3);
}