c - 从 csv 文件读取和动态内存分配

标签 c dynamic-memory-allocation

我的代码有内存泄漏问题。我不知道我哪里出错了。下面是代码:我正在尝试从 csv 文件中读取并存储特定的列。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
    FILE *result = fopen ("C:\\Users\\pa1rs\\Desktop\\local.csv", "w");

    const char *text = "LOA,NAME,";
    fprintf (result, "%s", text);
    char *token;
    char *endToken;
    int lines = 0;
    char ch;                            /* should check the result */
    FILE *file = fopen ("C:\\Users\\pa1rs\\Desktop\\samplee.csv", "r");
    char line[300];
    if (file == NULL) {
        perror ("Error opening the file");
    } else {
        while (!feof (file)) {
            ch = fgetc (file);
            if (ch == '\n') {
                lines = lines + 1;
            }
        }
        //printf(" no of lines existing in the file %d\n\n", lines);
    }
    fseek (file, 0, SEEK_SET);
    while ((ch = fgetc (file)) != '\n') {
        // we don't need the first line on sample.csv
        // as it is just the description part
    }
    int s[lines - 1];
    int j = 0;
    char *N[lines - 1];
    while (fgets (line, sizeof (line), file)) {
        int i = 0;
        token = line;
        do {
            endToken = strchr (token, ',');
            if (endToken)
                *endToken = '\0';
            if (i == 3) {
                s[j] = atoi (token);
            }
            if (i == 12) {
                N[j] = (char *) malloc (strlen (token) * sizeof (char));
                strcpy (N[j], token);
            }

            if (endToken)
                token = endToken + 1;
            i++;
        } while (endToken);
        j = j + 1;
    }
//******************************************************unigue loa
    int count = 0;
    int g = 0;
    int h = 0;
    int LOA[lines - 1];
    int dd = 0;
    for (dd = 0; dd < lines - 1; dd++) {
        LOA[dd] = 0;
    }
    for (g = 0; g < lines - 1; g++) {
        for (h = 0; h < count; h++) {
            if (s[g] == LOA[h])
                break;
        }
        if (h == count) {
            LOA[count] = s[g];
            count++;
        }
    }
    int xw = 0;
    for (xw = 0; xw < count; xw++) {
        //printf("%d \t",LOA[xw]);
    }

    //printf("LOA Array Length is: %d \n",count);


    //********************************************************
    ////FOR UNIQUE NAMES ARRAY


    //printf("No of unique names are %d",county);
    //FOR UNIQUE CAUSES ARRAY
    char *sa[9] =
        { "Monticello", "Valparaiso", "Crown Point", "Plymouth", "Goshen",
"Gary", "Hammond", "Laporte", "Angola" };
    int countz = 0;
    int gz = 0;
    int hz = 0;
    char *LOAz[lines - 1];
    int zero2 = 0;
    for (zero2 = 0; zero2 < lines - 1; zero2++) {
        LOAz[zero2] = NULL;
    }
    for (gz = 0; gz < lines - 1; gz++) {
        for (hz = 0; hz < countz; hz++) {
            if (strcmp (N[gz], LOAz[hz]) == 0)
                break;
        }
        if (hz == countz) {
            LOAz[countz] = (char *) malloc (strlen (N[gz]) * sizeof (char));
            strcpy (LOAz[countz], N[gz]);
            countz++;
        }
    }
    int nz = 0;
    for (nz = 0; nz < countz; nz++) {
        fprintf (result, "%s,", LOAz[nz]);
    }
    fprintf (result, "\n");
    // printf("%d",countz);
    //*****************************
    int i = 0;
    int jjj = 0;
    int xxx = 0;
    int ggg = 0;
    int k = 0;
    int kount[count][countz];
    for (xxx = 0; xxx < count; xxx++) {
        for (ggg = 0; ggg < countz; ggg++) {
            kount[xxx][ggg] = 0;
        }
    }
    for (i = 0; i < count; i++) {
        for (k = 0; k < countz; k++) {
            for (jjj = 0; jjj < lines - 1; jjj++) {
                if (LOA[i] == s[jjj]) {
                    if (strcmp (LOAz[k], N[jjj]) == 0) {
                        kount[i][k]++;

                    }
                }

            }
        }
    }

    int ig = 0;
    int ik = 0;
    for (ig = 0; ig < count; ig++) {
        fprintf (result, "%d,%s", LOA[ig], sa[ig]);
        for (ik = 0; ik < countz; ik++) {
            fprintf (result, ",%d", kount[ig][ik]);
        }
        fprintf (result, "\n");
    }
    int rrr = 0;
    free (N);
    for (rrr = 0; rrr < lines - 1; rrr++) {
        free (LOAz[rrr]);
    }

    //*****************************
    //fclose(result);
    fclose (file);
    return 0;
}

我在这里得到的行是 13761 并且 LOAz 是用数组大小​​ lines-1=13761 声明的,但是我在这里得到的唯一行只有 49,所以我正在为此重新分配内存,其余未使用,我认为问题从那里开始。 请帮忙!提前致谢。

最佳答案

代码中的一个问题是没有为字符串分配足够的内存。例如,在这些行中:

N[j] = (char*) malloc(strlen(token) * sizeof(char));
strcpy(N[j], token);
// ...
LOAz[countz] = (char*) malloc(strlen(N[gz]) * sizeof(char));
strcpy(LOAz[countz], N[gz]);

问题在于 strlen 返回字符串中非零符号的数量。但是,要存储字符串,您还需要一个字节,还要存储零终止字符,因此存储 s 的缓冲区大小至少应为 strlen(s) + 1.

此外,更好的编码风格是 to avoid casting the return value of malloc .

关于c - 从 csv 文件读取和动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35223974/

相关文章:

c++ - 可用动态数组内存错误 : _BLOCK_TYPE_IS_VALID

c++ - 减少 cuda 内核运行时 : dynamic memory allocation of matrices in kernel

c - 操纵随机数数组

c++ - 以 FreeBSD 作为远程主机的 CLion 完全远程模式

c - 如何在 C 文件中包含 gtk/gtk.h

c - 跨线程释放内存

c - 将读数传感器作为消息发送到接收节点

c - C语言中位图的理解和获取信息

c - 二维动态分配数组可以访问比分配大小更多的内存

c - 函数 free() 不会从 vector 中取消分配内存