简体   繁体   English

在C中写入char *数组会引发segfault

[英]Writing to char* array in C throws segfault

I'm an infosec student, who has just begun learning C. I've been given an assignment to write a simple translation program using this prototype: char* dictionary[number_of_words][2]; 我是一名信息安全专业的学生,​​刚刚开始学习C。我被分配了一个使用此原型编写简单翻译程序的程序: char* dictionary[number_of_words][2]; .

The output should look something like this: 输出应如下所示:

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

My current (work in progress) code looks like this: 我当前的代码(正在进行中)如下所示:

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;
 }

The code throws no errors when compiled with gcc -Wall main.c , but this is the behaviour I get: 使用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)

There's a fundamental flaw somewhere in my thought process. 我的思考过程中存在一个基本缺陷。 Any help/heads up is very appreciated. 任何帮助/注意都非常感谢。 Cheers! 干杯!

Let's look at this part of your code: 让我们看一下代码的这一部分:

char* dictionary[size][2];

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

Each dictionary[i][j] is a pointer to char , but you haven't set them to point anywhere meaningful yet - each array element contains some random bit pattern that may or may not correspond to a writable address. 每个dictionary[i][j]都是指向char的指针,但是您尚未将它们设置为指向有意义的任何地方-每个数组元素都包含一些随机位模式,该模式可能对应也可能不对应可写地址。 Your first few entries get written somewhere , but eventually you try to write to a memory location you don't own or don't have access to. 您的前几个条目会写到某个地方 ,但最终您尝试写到一个您不拥有或无法访问的存储位置。

You will need to set aside additional memory to store each individual string. 您将需要预留额外的内存来存储每个单独的字符串。 You either need create a 3D array of char (not char * ): 您要么需要创建一个char的3D数组(不是char * ):

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

or you will need to dynamically allocate memory for each array entry: 否则您将需要为每个数组条目动态分配内存:

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);

If you allocate memory dynamically, you will need to explicitly free it when you're done: 如果动态分配内存,则需要在完成后显式free内存:

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

instead of messing around with arrays of multiple dimensions, I suggest you use structures: 建议您不要使用多个维度的数组,而建议使用结构:

#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
}

fgets(dictionary[i][j],100,stdin); reads from an uninitialized variable ( dictionary[i][j] was never given a value), which has undefined behavior. 从未初始化的变量( dictionary[i][j]从未提供值)中读取,该变量具有未定义的行为。

Also, i is going out of bounds later. 另外, i以后会越界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM