3输入后总是发生分段故障

时间:2014-07-17 16:32:55

标签: c segmentation-fault

我有以下代码接受来自用户的任意数量的行并打印出长度为>的行。 80个字符: -

#include <stdio.h>
#include <stdlib.h>
#include "shared.h"
#include <string.h>

int MAXLINE =  10;
int INCREMENT = 10;
int NUM = 1;

char* longest = NULL;
char* line = NULL;
char** row = NULL;

void _memcleanup(){

    int i =0;

    free(line);
    free(longest);

    for(i=0;i<NUM;i++){
      free(row[i]);
    }

    free(row);
}

void print_lines(int len){

  int i;

  for(i=0;i<len;i++){

    if(strlen(row[i])>80){
    printf("%s\n",row[i]);
    }

  }


}

void copy(char** longest, char** line){

  int i=0;

  char* temp = realloc(*longest,(MAXLINE)*sizeof(char));

      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      *longest = temp;

      while(((*longest)[i] = (*line)[i]) != '\0'){
    ++i;
      }

      longest[i] = '\0';

}

void store(char** s, int pos){

  int i=0;



  char* temp = realloc(row[pos],(MAXLINE)*sizeof(char));

      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      row[pos] = temp;

      while((row[pos][i] = (*s)[i]) != '\0'){
    ++i;
      }

      row[pos][i] = '\0';

}

int _getline(char** s, int pos){

  int i,c;

  for(i=0; ((c=getchar())!=EOF && c!='\n'); i++){

    if(i == MAXLINE - 2){

      char* temp = realloc(*s,(MAXLINE + INCREMENT)*sizeof(char));

      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      *s= temp;

      MAXLINE += INCREMENT;
    }
    (*s)[i] = c;
  }

  if(c == '\n'){
    (*s)[i++] = c;
  }

  (*s)[i]= '\0';

  store(s, pos);

  return i;
} 

int main(){

  int max=0, len, i=0;

  line = malloc(MAXLINE*sizeof(char));
  longest = malloc(MAXLINE*sizeof(char));

  //array of character pointers
  row = malloc(NUM*sizeof(char*));

  //allocate memory for each row in the array
  for(i = 0; i < NUM; i++){
    row[i]= malloc(MAXLINE*(sizeof(char)));
  }

  i=0;

  //for(i=0; len = _getline(&line)) > 0; i++){
  while((len = _getline(&line, i)) > 0){
    printf("%d %d", len, MAXLINE);

    /* if(len > max){ */
    /*   max = len; */
    /*   copy(&longest, &line); */
    /* } */

    i++;
  }
    /* if(max>0){ */
    /*   printf("%s",longest); */
    /* } */

  print_lines(i);

    _memcleanup();
  return 0;

}

我追随的想法是当行数超过NUM时重新分配2D数组。现在测试它,我将NUM设置为1.但是,即使这样做,程序也很乐意在第4个输入上接受最多3个输入和段错误,即在程序的上下文中pos = 3。

为什么它接受3个输入(理想情况下它应该给出segfault pos = 1本身,因为我只给出了1的大小而我没有为2D数组分配更多的空间)

工作代码如下:

#include <stdio.h>
#include <stdlib.h>
#include "shared.h"
#include <string.h>

int MAXLINE =  10;
int INCREMENT = 10;
int NUM = 1;

char* longest = NULL;
char* line = NULL;
char** row = NULL;

void _memcleanup(){

    int i =0;

    free(line);
    free(longest);

    for(i=0;i<NUM;i++){
      free(row[i]);
    }

    free(row);
}

void print_lines(int len){

  int i;

  for(i=0;i<len;i++){

    if(strlen(row[i])>80){
    printf("%s\n",row[i]);
    }

  }


}

void copy(char** longest, char** line){

  int i=0;

  char* temp = realloc(*longest,(MAXLINE)*sizeof(char));

      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      *longest = temp;

      while(((*longest)[i] = (*line)[i]) != '\0'){
    ++i;
      }

      longest[i] = '\0';

}

void store(char** s, int pos){

  int i=0;

  if(pos == NUM){
    char** temprow = realloc(row, (NUM + INCREMENT)*sizeof(char*));

    if(temprow == NULL){
            printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);      
    }

    row = temprow;
    //allocate space for extra elements
    for(i=NUM;i<NUM+INCREMENT;i++){
      row[i] = malloc(MAXLINE*sizeof(char));
    }

    NUM = NUM + INCREMENT; 

  }

  char* temp = realloc(row[pos],(MAXLINE)*sizeof(char));

      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      row[pos] = temp;

      while((row[pos][i] = (*s)[i]) != '\0'){
    ++i;
      }

      row[pos][i] = '\0';

}

int _getline(char** s, int pos){

  int i,c;

  for(i=0; ((c=getchar())!=EOF && c!='\n'); i++){

    if(i == MAXLINE - 2){

      char* temp = realloc(*s,(MAXLINE + INCREMENT)*sizeof(char));

      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      *s= temp;

      MAXLINE += INCREMENT;
    }
    (*s)[i] = c;
  }

  if(c == '\n'){
    (*s)[i++] = c;
  }

  (*s)[i]= '\0';

  store(s, pos);

  return i;
} 

int main(){

  int max=0, len, i=0;

  line = malloc(MAXLINE*sizeof(char));
  longest = malloc(MAXLINE*sizeof(char));

  //array of character pointers
  row = malloc(NUM*sizeof(char*));

  //allocate memory for each row in the array
  for(i = 0; i < NUM; i++){
    row[i]= malloc(MAXLINE*(sizeof(char)));
  }

  i=0;

  //for(i=0; len = _getline(&line)) > 0; i++){
  while((len = _getline(&line, i)) > 0){
    printf("%d %d", len, MAXLINE);

    /* if(len > max){ */
    /*   max = len; */
    /*   copy(&longest, &line); */
    /* } */

    i++;
  }
    /* if(max>0){ */
    /*   printf("%s",longest); */
    /* } */

  print_lines(i);

    _memcleanup();
  return 0;

}

2 个答案:

答案 0 :(得分:1)

你在问:

  

为什么它接受3个输入(理想情况下它应该给出segfault pos = 1本身,因为我只给出了1的大小而我没有为2D数组分配更多的空间)

并且您是对的,如果您仅为一行分配内存,则在您尝试访问rows[1]时会调用未定义的行为。但这种行为只是 - 未定义 - 这意味着你不能依赖程序崩溃。任何事情都可能发生,包括程序似乎完美无缺地运作

答案 1 :(得分:0)

在main()中,而不是使用

while((len = _getline(&line, i)) > 0){  

使用

while(i< NUM)
{
  len = _getline(&line, i);

对于我这个代码更改,它工作正常。