Linux中发生了分段错误但在Mac

时间:2015-09-14 11:57:51

标签: c linux eclipse xcode

我有一个c代码,它在我的Mac笔记本电脑中用Xcode编写,但它在Linux系统中没有用。

我通过两种方式运行此代码:

1.One在Eclipse中运行但是while循环看起来并不完整。请在下面找到以下信息:

  

请等待计算......

但是在控制台中没有更多消息。看起来虽然循环因某种原因无法完成。

2.第二种方式是我通过以下命令直接在Linux环境中编译代码:

  

cc -std = c99 main.c -o main

然后按命令运行:

  

./主

该消息显示:

  

请等待计算...分段错误(核心转储)

我是通过gdb检查的

  

编程接收信号SIGSEGV,分段故障。   0x00007ffff7a9bd4a在? ()来自/lib/x86_64-linux-gnu/libc.so.6

我的数据保存在:

  

/home/alan_yu/workspace/scandi.csv

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

char **split(char *line, char sep, int fields) {

    char **r = (char **)malloc(fields * sizeof(char*));

    int lptr = 0, fptr = 0;

    r[fptr++] = line;

    while (line[lptr]) {

        if (line[lptr] == sep) {

            line[lptr] = '\0';

            r[fptr] = &(line[lptr+1]);

            fptr++;

        }

        lptr++;

    }

    return r;

}

int cmpfunc (const void * a, const void * b)

{

    return *(double *)a > *(double *)b ? 1 : -1;

}

#define LINE_SIZE 1000000

#define EXPECTED_STOCK_SIZE 10000000

void calculate2(char * fileName) {

     printf("Please wait while calculating...\n");

    // Open the file for reading.

    FILE *file = fopen(fileName, "r");

    // maximun size of the line to read.

    // memory allocation for the line to read.

    char* line = malloc(LINE_SIZE);

//    char **stockNameArray = malloc( sizeof(char *) * EXPECTED_STOCK_SIZE);

//    int stockNameArrayPos = 0;

    double *bidArray = malloc( sizeof(double) * EXPECTED_STOCK_SIZE );

    int bidArrayPos = 0;

    double *askArray = malloc( sizeof(double) * EXPECTED_STOCK_SIZE);

    int askArrayPos = 0;

    double *spreadArray = malloc( sizeof(double) * EXPECTED_STOCK_SIZE);

    int spreadArrayPos = 0;

    double sum=0;

    int i=0,j=0;

    while (fgets(line, LINE_SIZE, file)!= NULL){

    //  printf("Please wait while ...%d\n ", j);
        j++;
        char **fields = split(line, ',', 15);

        const char * volvbEquity = "VOLVB SS Equity";

        int comp = strcmp(fields[0], volvbEquity);

        if (comp == 0) {

            double bidValue = atof(fields[2]);

            double askValue = atof(fields[3]);

            bidArray[bidArrayPos++] = bidValue;

            askArray[askArrayPos++] = askValue;

            if (askValue - bidValue > 0) {

                double spreadValue = ((askValue - bidValue) / (askValue + bidValue) * 20000);

                spreadArray[spreadArrayPos++] = spreadValue;

                sum = sum + spreadValue;

            }

        }

    }


    //quick sort the spread

    qsort(spreadArray, spreadArrayPos, sizeof(double), cmpfunc);

    int mediumPos;

    double mean;

    double medium;

    if(spreadArrayPos % 2 == 0) {

        mediumPos = spreadArrayPos / 2;

        medium = (spreadArray[mediumPos] + spreadArray[mediumPos+1]) / 2;

    } else {

        mediumPos = (spreadArrayPos)/2 + 1;

        medium = spreadArray[mediumPos];

    }

    mean = sum / spreadArrayPos;

    printf("Please find mean and medium %f %f\n", mean, medium);

    free(bidArray);

    free(askArray);

    free(spreadArray);

}

int main(int argc, char **argv) {

    calculate2("/home/alan_yu/workspace/scandi.csv");

    return(0);

}

4 个答案:

答案 0 :(得分:0)

您需要检查fopen的返回值!我建议对malloc做同样的事情,但malloc由于缺少文件或打字错误而失败的可能性要小得多 ,特别是如果你是分配大块!您不希望取消引用空指针,对吧?

我假设每行至少有四个以逗号分隔的字段,因为您使用的是fields[3]。您应该在这里找出如何防止使用未初始化的值。我首先重新设计split,以便在输出中有一些终端NULL值或某些内容(当我们讨论该主题时,请不要忘记free返回值)。

你有可能除以零吗?这是你需要防范的其他事情。

当项目相同时,cmpfunc不应该返回0吗?我发现当qsortbsearch的比较函数的返回值不一致时,实现会崩溃。

您在评论中声称您的行有十五个逗号。这意味着您有16个字段(在下面计算),因为字段数为n+1,其中n是分隔符的数量。

field1, field2, field3, field4,
field4, field6, field7, field8,
field9, field10,field11,field12,
field13,field14,field15,field16

此表中有十五个逗号和十六个字段。 但是,您只能分配十五个字段。这是缓冲区溢出,更典型的未定义行为。

答案 1 :(得分:0)

On Linux, always run the program in valgrind if it is crashing.

It will not only tell you exactly what is wrong in your code, but also specify what code lines are responsible for the error.

答案 2 :(得分:0)

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

void split(char *line, char sep, char **fields) {

    int lptr = 0, fptr = 0;

    fields[fptr++] = line;

    while (line[lptr]) {

        if (line[lptr] == sep) {

            line[lptr] = '\0';

            fields[fptr] = &(line[lptr+1]);

            fptr++;

        }

        lptr++;

    }
}

int cmpfunc (const void * a, const void * b) {
    return *(double *)a > *(double *)b ? 1 : -1;
}

#define LINE_SIZE 1000000

#define EXPECTED_STOCK_SIZE 10000000

#define COLUMN_NUM 15

void calculate2(char * fileName) {

     printf("Please wait while calculating...\n");

    // Open the file for reading.
    FILE *file = fopen(fileName, "r");

    // maximun size of the line to read.
    // memory allocation for the line to read. 
    char* line = malloc(LINE_SIZE);

//    char **stockNameArray = malloc( sizeof(char *) * EXPECTED_STOCK_SIZE);
//    int stockNameArrayPos = 0;

    double *bidArray = malloc( sizeof(double) * EXPECTED_STOCK_SIZE );

    int bidArrayPos = 0;

    double *askArray = malloc( sizeof(double) * EXPECTED_STOCK_SIZE);

    int askArrayPos = 0;

    double *spreadArray = malloc( sizeof(double) * EXPECTED_STOCK_SIZE);

    int spreadArrayPos = 0;

    double sum=0;

    int i=0,j=0;

    while (fgets(line, LINE_SIZE, file)!= NULL){

    //  printf("Please wait while ...%d\n ", j);
        j++;
        char **fields = malloc(sizeof(char *) * COLUMN_NUM);
        split(line, ',', fields);

        const char * volvbEquity = "VOLVB SS Equity";

        int comp = strcmp(fields[0], volvbEquity);

        if (comp == 0) {

            double bidValue = atof(fields[2]);

            double askValue = atof(fields[3]);

            bidArray[bidArrayPos++] = bidValue;

            askArray[askArrayPos++] = askValue;

            if (askValue - bidValue > 0) {

                double spreadValue = ((askValue - bidValue) / (askValue + bidValue) * 20000);

                spreadArray[spreadArrayPos++] = spreadValue;

                sum = sum + spreadValue;

            }

        }

        // free memory for fields.
        free(fields);

    }

    // free memory for the line variable.
    free(line);

    //quick sort the spread
    qsort(spreadArray, spreadArrayPos, sizeof(double), cmpfunc);

    int mediumPos;
    double mean;
    double medium;

    if(spreadArrayPos % 2 == 0) {
        mediumPos = spreadArrayPos / 2;
        medium = (spreadArray[mediumPos] + spreadArray[mediumPos+1]) / 2;

    } else {
        mediumPos = (spreadArrayPos)/2 + 1;
        medium = spreadArray[mediumPos];
    }

    mean = sum / spreadArrayPos;

    printf("Please find mean and medium %f %f\n", mean, medium);

    free(bidArray);

    free(askArray);

    free(spreadArray);

}

int main(int argc, char **argv) {

    calculate2("/home/alan_yu/workspace/scandi.csv");

    return(0);

}

答案 3 :(得分:0)

最后,我发现问题来自

.h files

我已将其更改为

while (fgets(line, LINE_SIZE, file)!= NULL){
char **fields = split(line, ',', 15);

我没有尝试在while循环之后为**字段分配大内存,因为它占用了我的机器太多的内存。

如果我这样做,在gcc编译下看起来:

char **fields = malloc(sizeof(char *) * 15 * 10000);
while (fgets(line, LINE_SIZE, file)!= NULL){

它不会覆盖上次的**字段。但它适用于Mac

不确定是否正确?

最后,感谢你们所有人为我的问题提供帮助。