【问题标题】:How to assign a temp value to a 2d array如何将临时值分配给二维数组
【发布时间】:2019-03-13 20:56:57
【问题描述】:

所以我有一个二维结构数组,用于存储来自 csv 文件的数据。我正在从文件中读取字符串,然后我想将它们在二维数组中的值分配为该字符串。因此,例如位置 [0][0] 将是“红色”,而位置 [1][1] 将是“蓝色”或其他东西。问题是我正在从文件中读取字符并将它们存储在一个临时字符串中,然后我想将该临时字符串值分配给我所在的当前位置。所以我将 temp 设为“red”,我希望 [0][0] 为“red”,然后它从文件中读取更多内容,temp 现在为“blue”,我希望 [0][1] 为“blue” ”。当我分配 [0][0]=temp 然后 [0][1]=temp 它们相互覆盖时(因为它是一个指针)。我已经尝试过 strdup(temp) 但这似乎并不能解决问题,因为它们有时仍然会相互重写。我知道我可以使用 strcpy 但是对于 strcpy 我必须有另一个字符串来复制它所以我尝试了每次只创建一个新的 char 数组,但这也不起作用。它仍然被覆盖。我知道我可以解决这个问题,如果每次我分配一个值时,我都会创建一个带有新名称的新 char 数组并指向该 char 数组,但这是针对一个非常大的 csv 文件,所以我必须创建大约 1000 万个char 数组,我不知道该怎么做,似乎应该有一个更简单的方法。

非常感谢任何帮助,谢谢!

struct node {
    char* value;
};

char temp[500];
struct node ** arrayofnodes[35];
for(int i=0; i<35; i++) {
    arrayofnodes[i] = malloc(test * sizeof (struct node));
    for(int j=0; j<test; j++) arrayofnodes[i][j] = malloc(sizeof (struct node));
}


//(all of this below happens inside a function because it is going to be called like 10 million times)
    arrayofnodes[row][count]->value=temp; //way 1
    arrayofnodes[row][count]->value=strdup(temp); //way 2
    char fun[500];
    strcpy(fun,temp);
    arrayofnodes[row][count]->value=fun;//way 3

【问题讨论】:

标签: c arrays csv multidimensional-array struct


【解决方案1】:

arrayofnodes[i] = malloc(N * sizeof (struct node)); 为 N 个结构腾出足够的空间。你想要的是 N 结构指针的空间。

但是,我认为这不是您的主要问题。只有“方式 2”是有效的 - 您确实需要为您读取的每个新字符串创建存储空间。 “方式一”重用temp存储,“方式三”重用“乐趣”存储,退出功能即失效。

如果“方式 2”不适合您,我会查看生成 rowcount 的代码。这些索引是否总是分别小于35test

【讨论】:

    【解决方案2】:

    使用 malloc 或 strdup 时,需要额外的 16 字节空间进行管理。
    当你分配大量的小内存时,这额外的空间也会占用大量内存。
    所以考虑自己管理内存,或者tcmalloc,jemalloc

    下面是测试数据:

    gcc -otest test.c -Wall -O3 -g

    [test_strdup] cost time: 1085247 us, use memory: 839.81 MB
    [test_optimized] cost time: 394635 us, use memory: 411.71 MB
    

    gcc -otest test.c -Wall -O3 -g -ltcmalloc

    [test_strdup] cost time: 627160 us, use memory: 461.07 MB
    [test_optimized] cost time: 397938 us, use memory: 422.85 MB
    

    gcc -otest test.c -Wall -O3 -g -ljemalloc

    [test_strdup] cost time: 749875 us, use memory: 481.77 MB
    [test_optimized] cost time: 330825 us, use memory: 451.96 MB
    

    下面是测试代码

    只是为了比较内存分配,测试代码有内存泄漏。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/time.h>
    #include <sys/sysinfo.h>
    
    #define ROWS 35
    #define COLS (1000*10000/ROWS)
    #define MB   (1024*1024)
    #define TEST_STR "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    struct node {
        char *value;
    };
    
    long current_time()
    {
        struct timeval tv;
        gettimeofday(&tv, NULL);
        return tv.tv_sec * 1000000L + tv.tv_usec;
    }
    
    long current_usemem()
    {
        FILE *fp;
        long resident = 0;
    
        fp = fopen("/proc/self/statm", "r");
        if (fp) {
            if (fscanf(fp, "%*s %ld ", &resident) != 1)
                resident = 0;
            fclose(fp);
        }
        resident *= 4096;
    
        return resident;
    }
    
    void test_strdup()
    {
        char temp[500];
        struct node **arrayofnodes[ROWS];
        int i, j;
        long start_time, end_time;
        long start_usemem, end_usemem;
    
        strcpy(temp, TEST_STR);
        start_usemem = current_usemem();
        start_time = current_time();
    
        for(i = 0; i < ROWS; i++) {
            arrayofnodes[i] = (struct node **)malloc(COLS * sizeof(struct node *));
            for(j = 0; j < COLS; j++) {
                arrayofnodes[i][j] = (struct node *)malloc(sizeof (struct node));
            }
        }
    
        for(i = 0; i < ROWS; i++) {
            for(j = 0; j < COLS; j++) {
                arrayofnodes[i][j]->value = strdup(temp);
            }
        }
    
        end_time = current_time();
        end_usemem = current_usemem();
        printf("[%s] cost time: %ld us, use memory: %.2f MB\n",
               __FUNCTION__, end_time - start_time,
               (end_usemem - start_usemem) / 1024.0 / 1024);
    }
    
    struct memory_chunk {
        struct memory_chunk *next;
        char *cur;
        char *end;
        char buf[0];
    };
    
    struct memory_pool {
        struct memory_chunk *head;
    };
    
    void *pool_alloc(struct memory_pool *pool, size_t size)
    {
        void *ret;
        struct memory_chunk *chunk;
    
        chunk = pool->head;
        if (chunk == NULL || chunk->cur + size >= chunk->end) {
            size_t len = (size < MB ? MB : size + sizeof(*chunk));
            chunk = (struct memory_chunk *)malloc(len);
            chunk->next = pool->head;
            chunk->end = (char *)chunk + len;
            chunk->cur = chunk->buf;
            pool->head = chunk;
        }
    
        ret = chunk->cur;
        chunk->cur += size;
        return ret;
    }
    
    char *pool_strdup(struct memory_pool *pool, const char *s)
    {
        size_t size = strlen(s) + 1;
        void *ret = pool_alloc(pool, size);
        memcpy(ret, s, size);
        return ret;
    }
    
    void test_optimized()
    {
        char temp[500];
        struct node ***arrayofnodes;
        int i, j;
        long start_time, end_time;
        long start_usemem, end_usemem;
        struct memory_pool pool = {NULL};
    
        strcpy(temp, TEST_STR);
        start_usemem = current_usemem();
        start_time = current_time();
    
        arrayofnodes = (struct node ** *)pool_alloc(&pool, ROWS * sizeof(struct node **));
        for(i = 0; i < ROWS; i++) {
            arrayofnodes[i] = (struct node **)pool_alloc(&pool, COLS * sizeof(struct node *));
            for(j = 0; j < COLS; j++) {
                arrayofnodes[i][j] = (struct node *)pool_alloc(&pool, sizeof(struct node));
            }
        }
    
        for(i = 0; i < ROWS; i++) {
            for(j = 0; j < COLS; j++) {
                arrayofnodes[i][j]->value = pool_strdup(&pool, temp);
            }
        }
    
        end_time = current_time();
        end_usemem = current_usemem();
        printf("[%s] cost time: %ld us, use memory: %.2f MB\n",
               __FUNCTION__, end_time - start_time,
               (end_usemem - start_usemem) / 1024.0 / 1024);
    
    }
    
    int main()
    {
        test_strdup();
        test_optimized();
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2018-05-17
      • 2023-03-06
      相关资源
      最近更新 更多