随机数组(seg fault)

时间:2013-10-27 21:55:45

标签: c arrays segmentation-fault

所以我应该创建一个完成的功能: 目的:程序调整文本文件的行

  • 将文件读入数组
  • 计算行数和最大长度
  • 计算数组的最大宽度
  • 获取指向开头的文件指针
  • 为动态字符串数组保留内存
  • 读取一行并存储在已分配的内存中
  • 将\ n转到\ 0
  • 从数组打印行(测试)
  • 随机播放阵列
  • 从数组打印行(测试)
  • 可用内存和关闭文件

(只是为了给出一些背景知识)

但是,当我去打印混洗数组时,我会遇到分段错误。有时,它会打印一个或两个字符串,但有时它只是说“混洗数组”,然后我得到一个分段错误。有什么想法吗?

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

// Accepts: command line input
// Returns: 0 if no error

int main(int argc, char *argv[] ){
    int x = 0, i, lineCount = 0, maxLen = 0;
    char line[500], temp;
    FILE *file = fopen( argv[1], "r" );
//  check if file exists
    if (file == NULL){
        printf("Cannot open file\n");
        return 1;
    }
//  Gets lines, max length of string    
    while (fgets(line, sizeof(line), file) != NULL){
        lineCount++;
        if (strlen(line) > maxLen)
            maxLen = strlen(line);
    }
    rewind(file);
    char *lineArray[lineCount];
    while (fgets(line, sizeof(line), file) != NULL) {
            lineArray[x] = malloc(strlen(line));
        if (lineArray[x] == NULL){
            printf("A memory error occurred.\n");
            return(1);
        }
            strcpy(lineArray[x], line);
//  change \n to \0
        lineArray[x][strlen(lineArray[x])-1] = '\0';
        x++;
    }
    printf("File %s has %d lines with maximum length of %d characters\n",
        argv[1], lineCount, maxLen);
    printf("Original Array\n");
    for (x = 0; x < lineCount; x++)
        printf("%2d %s\n", x, lineArray[x]);
//  Shuffle array
    srand( (unsigned int) time(NULL));
    for (x = lineCount - 1; x >= 0; x--){
        i = (int) rand() % lineCount;
        temp = lineArray[x];
        lineArray[x] = lineArray[i];
        lineArray[i] = temp;
    }
    printf("\nShuffled Array\n");
    for (x = 0; x < lineCount; x++)
        printf("%2d %s\n", x, lineArray[x]);
//  free allocated memory
    for (x = 0; x < lineCount; x++)
        free(lineArray[x]);
    free(lineArray);
    fclose(file);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我机器上运行cc的输出使错误非常明显。

$ cc tmp.c -o tmp
tmp.c:46:14: warning: incompatible pointer to integer conversion assigning to
      'char' from 'char *'; dereference with * [-Wint-conversion]
        temp = lineArray[x];
             ^ ~~~~~~~~~~~~
               *
tmp.c:48:22: warning: incompatible integer to pointer conversion assigning to
      'char *' from 'char'; take the address with & [-Wint-conversion]
        lineArray[i] = temp;
                     ^ ~~~~
                       &
2 warnings generated.

您需要修复变量,不能使用char来打算使用char *

对不起,为了说得更清楚:

char line[500], temp;

应该是:

 char line[500], *temp;

如果您想澄清为什么会这样,请告诉我。

最后,它不是C风格(除非你编写嵌入式C)在方法的顶部声明变量。将它们声明为尽可能接近使用点。它可以更容易地找到您声明的内容。例如,temp可以在循环上方声明,在循环中使用它,甚至更好。

哦,并且:

$ cc --version
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

答案 1 :(得分:0)

你在这做什么?

free(lineArray);

lineArray是一个数组,定义如下:

char *lineArray[lineCount];

你不应该尝试free(),因为你首先没有malloc()

最重要的是,这个:

char line[500], temp;

应该是这样的:

char line[500], *temp;

正如您的编译器应该试图告诉您的那样。

可能还有其他问题,但由于您选择不提供输入文件或提供不需要的程序版本,因此没有人可以编译并运行它来查找。

编辑:进行上述更改,按照另一个答案的建议将lineArray[x] = malloc(strlen(line));更改为lineArray[x] = malloc(strlen(line) + 1);,并使用合适的输入文件,我得到以下输出:

paul@local:~/src/c/scratch$ ./sta testfile
File testfile has 4 lines with maximum length of 13 characters
Original Array
 0 john doe
 1 jane fish
 2 donny brutus
 3 fishy mcgee

Shuffled Array
 0 john doe
 1 jane fish
 2 fishy mcgee
 3 donny brutus
paul@local:~/src/c/scratch$

但你真的需要学习更好地使用编译器。你应该像这样调用gcc:

gcc -o myprog myfile.c -std=c99 -pedantic -Wall -Wextra

获取所有最有用的警告。