在C中写入char *数组会引发段错误

时间:2017-11-01 19:55:30

标签: c arrays pointers

我是一名信息安全学生,刚刚开始学习C.我已经获得了使用这个原型撰写简单翻译程序的任务:char* dictionary[number_of_words][2];

输出应该如下所示:

Enter # of words to add: 3

dictionary[0][0]= plane
dictionary[0][1]= Flugzeug
dictionary[1][0]= house
dictionary[1][1]= Haus
dictionary[2][0]= cat
dictionary[2][1]= Katze

Enter english word to translate: house
---> Haus

我当前的(正在进行中的)代码如下所示:

void clean_stdin(void);
int main(void)
{
     unsigned int i = 0,j = 0,size; 
     printf("Enter # of words to add: ");
     scanf("%u",&size);
     clean_stdin(); //clears input buffer

     char* dictionary[size][2];

     while(i <= size) 
     {   
         printf("dictionary[%u][%u]= ",i,j);
         fgets(dictionary[i][j],100,stdin);

         if(j >= 1)
         {
             j = 0;
             ++i; 
         }
         else
             j = 1;
         }   

     return 0;
 }

使用gcc -Wall main.c编译时,代码不会抛出任何错误,但这是我得到的行为:

Enter # of words to add: 3
dictionary[0][0]= plane
dictionary[0][1]= Flugzeug
dictionary[1][0]= house
dictionary[1][1]= Haus
fish: “./a.out” terminated by signal SIGSEGV (Adressbereichsfehler)

*****

Enter # of words to add: 4
dictionary[0][0]= plane
fish: “./a.out” terminated by signal SIGSEGV (Adressbereichsfehler)

我的思维过程中存在一个根本性的缺陷。任何帮助/抬头都非常感谢。干杯!

3 个答案:

答案 0 :(得分:1)

让我们看一下代码的这一部分:

char* dictionary[size][2];

 while(i <= size) 
 {   
     printf("dictionary[%u][%u]= ",i,j);
     fgets(dictionary[i][j],100,stdin);

每个dictionary[i][j]都是指向char的指针,但是你没有将它们设置为指向任何有意义的位置 - 每个数组元素都包含一些随机位模式,它可能对应于可写地址,也可能不对应。您的前几个条目已写入某处,但最终您尝试写入您不拥有或无权访问的内存位置。

您需要留出额外的内存来存储每个字符串。您需要创建一个char(不是char *)的3D数组:

#define MAX_STR_LEN 100
...
char dictionary[size][2][MAX_STR_LEN+1]; 

您需要为每个数组条目动态分配内存:

while ( i < size )  // <, not <=
{
  dictionary[i][j] = malloc( sizeof *dictionary[i][j] * (MAX_STR_LEN + 1));
  if ( !dictionary[i][j] )
  {
    // memory allocation failed, handle error
  }
  printf("dictionary[%u][%u]= ",i,j);
  fgets(dictionary[i][j],MAX_STR_LEN,stdin);

如果您动态分配内存,则在完成后需要明确free

for ( i = 0; i < size; i++ )
{
  free( dictionary[i][0] );
  free( dictionary[i][1] );
}

答案 1 :(得分:1)

而不是搞乱多维数组,我建议你使用结构:

#include <stdio.h>
#include <string.h>

int main()
{
    unsigned int size;
    printf("Enter # of words to add: ");
    if (scanf("%u", &size) != 1)
        return 1; // cannot convert input to integer

#define WORD_MAX_SIZE 100

    struct {
        char word[WORD_MAX_SIZE];
        char translation[WORD_MAX_SIZE];
    } dictionary[size];

    memset(dictionary, 0, sizeof(dictionary));

    for (int i = 0; i < size; i++) {
        printf("dictionary[%u].word= ", i);
        fgets(dictionary[i].word, WORD_MAX_SIZE, stdin);
        printf("dictionary[%u].translation= ", i);
        fgets(dictionary[i].translation, WORD_MAX_SIZE, stdin);
    }

    // do something with your stuff
}

答案 2 :(得分:0)

fgets(dictionary[i][j],100,stdin);从未初始化的变量读取(dictionary[i][j]从未被赋予值),其具有未定义的行为。

此外,i稍后会超出范围。