我在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
函数创建的第一个数组中的值。
我真的很感激被指向正确的方向。
答案 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()
功能的签名 - 至少有两个选项。
您可以更改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
进行比较。请注意,在使用分配的空间之前,代码会仔细检查分配是否成功。
或者,如果您喜欢双指针,则可以将指针传递给指向函数的指针:
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);
}