所以我有一个二维结构数组,用于存储csv文件中的数据。我正在从文件中读取字符串,然后要将2d数组中的值分配为该字符串。因此,例如,位置[0] [0]将为“红色”,位置[1] [1]将为“蓝色”或其他内容。问题是我正在从文件中读取字符并将它们存储在临时字符串中,然后我想将该临时字符串值分配给我所在的当前位置。因此,我将温度设为“红色”,并且我希望[0] [0]为“红色”,然后它从文件中读取更多信息,现在温度为“蓝色”,并且我希望[0] [1]为“蓝色” ”。当我分配[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
答案 0 :(得分:1)
arrayofnodes[i] = malloc(N * sizeof (struct node));
为N个结构留出足够的空间。您想要的是N个结构指针的空间。
但是,我认为这不是您的主要问题。只有“方式2”有效-您确实需要为读取的每个新字符串创建存储。 “方式1”正在重新使用temp
存储空间,而“方式3”正在重新使用“乐趣”存储空间,一旦退出该功能,该存储空间将无效。
如果“方式2”不适用于您,我将看一下生成row
和count
的代码。这些索引是否总是分别小于35
和test
?
答案 1 :(得分:0)
使用malloc或strdup时,需要额外的16个字节的空间用于管理。
当您分配大量小内存时,这些额外的空间也会占用大量内存。
因此,请考虑自己的管理内存,或tcmalloc,jemalloc
gcc -otest test.c-墙-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;
}