0

我正在尝试设置一个整数指针数组。程序应该将索引 i 处的指针设置为指向值为 2*i 的整数。然后程序应该打印出前 5 个指针元素的指针,它们应该是 0、2、4、6、8。

出于某种原因,我遇到了分段错误。谁能告诉我为什么会发生这种情况以及我能做些什么来解决它?

我试图用“ arr[index] = &i; ”替换最后一行,这不会给我一个分段错误,但仍然给我错误的结果。

帮助将不胜感激,刚开始的指针数组。

#include <stdio.h>

void setArr (int);

int * arr[10]; // array of 10 int pointers

int main(int argc, char *argv[])
{
    int i;

        setArr(0);
        setArr(1);
        setArr(2);
        setArr(3);
        setArr(4);


        for(i=0; i<5;i++) 
          printf("arr [%d] = %d\n", i, *arr[i]);  /* should be 0, 2, 4, 6, 8 */

    return 0;
}

/* set arr[index], which is a pointer, to point to an integer of value 2*index */
void setArr (int index){
  int i = 2 * index;
  * arr[index] = i;
}
4

3 回答 3

2

问题是您没有为数组中每个项目指向的内容分配内存。线

*arr[index] = i;

会将一些随机内存地址(最初在 中的arr[index])设置为 的值i

你应该做的是:

void setArr(int index)
{
    int *i = malloc(sizeof(int)); // allocate memory for the value
    *i = 2 * index; // set the value
    arr[index] = i; // make the array slot point at the value
}

但你需要确保free()以后的记忆。例如,在函数中的return 0;语句之前main(),放置:

for (i = 0; i < 5; i++)
    free(arr[i]);
于 2013-07-03T18:04:49.707 回答
0

这摘自 Yashavant P. Kanetkar 的Let Us "C"的第 9 章,应该澄清为什么你之前所做的没有奏效。

当我们使用二维字符数组时,我们可以自由地初始化我们声明数组的字符串,或者使用 scanf() 函数接收字符串。但是,当我们使用指向字符串的指针数组时,我们可以在声明数组的地方初始化字符串,但我们无法使用 scanf() 从键盘接收字符串。因此,以下程序永远不会成功。

main( )
{
char *names[6] ;
int i ;
for ( i = 0 ; i <= 5 ; i++ )
{
printf ( "\nEnter name " ) ;
scanf ( "%s", names[i] ) ;
}
}

该程序不起作用,因为;当我们声明数组时,它包含垃圾值。将这些垃圾值发送给 scanf() 作为它应该保存从键盘接收到的字符串的地址肯定是错误的。解决方案 如果我们一心想要使用 scanf() 从键盘接收字符串,然后将它们的地址存储在指向字符串的指针数组中,我们可以用稍微圆一点的方式来完成,如下所示。

#include "alloc.h"
main( )
352 Let Us C
{
char *names[6] ;
char n[50] ;
int len, i ;
char *p ;
for ( i = 0 ; i <= 5 ; i++ )
{
printf ( "\nEnter name " ) ;
scanf ( "%s", n ) ;
len = strlen ( n ) ;
p = malloc ( len + 1 ) ;
strcpy ( p, n ) ;
names[i] = p ;
}
for ( i = 0 ; i <= 5 ; i++ )
printf ( "\n%s", names[i] ) ;
}

在这里,我们首先在字符串 n[] 中使用 scanf() 接收了一个名称。然后我们使用 strlen() 找出了它的长度,并分配了空间来复制这个名称。这种内存分配是使用称为 malloc( ) 的标准库函数完成的。此函数需要分配的字节数并返回它分配的内存块的基地址。此函数返回的地址始终为 void * 类型。因此,它已使用称为类型转换的功能转换为 char *。类型转换将在第 15 章详细讨论。该函数的原型已在文件“alloc.h”中声明。因此我们有#included这个文件。但是为什么我们不使用数组来分配内存呢?这是因为对于数组,我们必须在编写程序时确定数组的大小。而且,在程序执行期间无法增加或减少数组大小。换句话说,当我们使用数组时,会发生静态内存分配。Chapter 9: Puppetting On Strings 353 与此不同的是,使用malloc()我们可以在执行期间动态分配内存。我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 当我们使用数组时,会发生静态内存分配。Chapter 9: Puppetting On Strings 353 与此不同的是,使用malloc()我们可以在执行期间动态分配内存。我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 当我们使用数组时,会发生静态内存分配。Chapter 9: Puppetting On Strings 353 与此不同的是,使用malloc()我们可以在执行期间动态分配内存。我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制

于 2013-07-03T18:42:58.073 回答
0

您需要为数组内的指针分配空间。

于 2013-07-03T18:03:39.117 回答