如何从终端为文本字符串分配内存?

时间:2016-12-15 14:38:05

标签: c memory-management

所以我有一个结构,我有我的char数组,它看起来像这样,

typedef struct data_{
  char * path;
} data;

我希望能够在终端中输入一个巨大的字符串并将字符串保存在这个数组中,我现在尝试的是这个,

data * data_ptr = malloc(sizeof(data));

data_ptr->path = malloc(sizeof(argv[i]) + 1); /*+ 1 to allocate an extra bit for I/O*/
strcpy(data->path, argv[i]);

在我退出程序之前,我释放了内存。但由于某种原因,我得到了分段错误。我已经在我的代码中的其他两个地方分配了内存,它们似乎工作得很好..我对Valgrind有点新意,并试图解释它试图告诉我问题是什么,但是它太大了对我来说太理解了。

==3117== Memcheck, a memory error detector
==3117== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3117== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==3117== Command: ./***
==3117== 
==3117== Syscall param open(filename) contains uninitialised byte(s)
==3117==    at 0x4F30460: __open_nocancel (syscall-template.S:84)
==3117==    by 0x4EB3ACD: _IO_file_open (fileops.c:221)
==3117==    by 0x4EB3D34: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:328)
==3117==    by 0x4EA7D33: __fopen_internal (iofopen.c:86)
==3117==    by 0x400AF7: search_file (in /home/***)
==3117==    by 0x400BE5: main (in /home/***)
==3117==  Uninitialised value was created by a stack allocation
==3117==    at 0x400B8C: main (in /home/***)
==3117== 
File does not exist.
==3117== Conditional jump or move depends on uninitialised value(s)
==3117==    at 0x4C2EDA1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3117==    by 0x400BF1: main (in /home/***)
==3117==  Uninitialised value was created by a stack allocation
==3117==    at 0x400B8C: main (in /home/***)
==3117== 
==3117== Invalid free() / delete / delete[] / realloc()
==3117==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3117==    by 0x400BF1: main (in /home/***)
==3117==  Address 0x400770 is in the Text segment of /home/***
==3117==    at 0x400770: _start (in /home/***)
==3117== 
==3117== Conditional jump or move depends on uninitialised value(s)
==3117==    at 0x4C2EDA1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3117==    by 0x400BFD: main (in /home/***)
==3117==  Uninitialised value was created by a stack allocation
==3117==    at 0x400B8C: main (in /home/***)
==3117== 
==3117== Invalid free() / delete / delete[] / realloc()
==3117==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3117==    by 0x400BFD: main (in /home/***)
==3117==  Address 0xffefffeb0 is on thread 1's stack
==3117== 
==3117== 
==3117== HEAP SUMMARY:
==3117==     in use at exit: 24 bytes in 1 blocks
==3117==   total heap usage: 3 allocs, 4 frees, 1,600 bytes allocated
==3117== 
==3117== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3117==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3117==    by 0x400882: parse (in /home/***)
==3117==    by 0x400BC6: main (in /home/***)
==3117== 
==3117== LEAK SUMMARY:
==3117==    definitely lost: 24 bytes in 1 blocks
==3117==    indirectly lost: 0 bytes in 0 blocks
==3117==      possibly lost: 0 bytes in 0 blocks
==3117==    still reachable: 0 bytes in 0 blocks
==3117==         suppressed: 0 bytes in 0 blocks
==3117== 
==3117== For counts of detected and suppressed errors, rerun with: -v
==3117== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)

是否有人能够看到我可能做错了什么?我对Valgrinds输出的看法是,我试图达到我无法访问的内存,或者我以某种奇怪的方式搞乱堆栈。但我不坦白说实话。

4 个答案:

答案 0 :(得分:3)

此:

data_ptr->path = malloc(sizeof(argv[i]) + 1)

是错误的,你不能使用sizeof在运行时获取字符串的长度。您必须使用strlen()

data_ptr->path = malloc(strlen(argv[i]) + 1);

如果有,可以使用strdup()进行分配和复制。使您不必记住+ 1

答案 1 :(得分:1)

argv[i]是字符串的指针,但不是字符串本身。因此,当您执行sizeof(argv[i])时,您只能获得指针的大小而不是指向的大小。

因此,当您执行malloc(sizeof(argv[i]) + 1)时,您将只分配59个字节(取决于指针大小,32位系统通常为4个字节,64位为8个字节)系统)。

您需要使用strlen来获取字符串的长度。

答案 2 :(得分:0)

使用strlen(argv [i])而不是sizeof

data * data_ptr = malloc(sizeof(data));

data_ptr->path = malloc(strlen(argv[i])); 
strcpy(data->path, argv[i]);

我希望i的值在0到argc的范围内。

答案 3 :(得分:0)

正如其他人指出的那样,您无法使用sizeof,在执行strlen时应使用malloc

但是,valgrind告诉你出了什么问题,你正试图打开一个不存在的文件。

==3117== Syscall param open(filename) contains uninitialised byte(s)
==3117==    at 0x4F30460: __open_nocancel (syscall-template.S:84)
==3117==    by 0x4EB3ACD: _IO_file_open (fileops.c:221)
==3117==    by 0x4EB3D34: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:328)
==3117==    by 0x4EA7D33: __fopen_internal (iofopen.c:86)
==3117==    by 0x400AF7: search_file (in /home/***)
==3117==    by 0x400BE5: main (in /home/***)
==3117==  Uninitialised value was created by a stack allocation
==3117==    at 0x400B8C: main (in /home/***)
==3117== 
File does not exist.

那么,也许你正试图打开一个虚假的文件(即filename的值是假的还是只是垃圾数据)?或者,您将虚假数据传递给fopen?你传递给fopen的路径是什么?