有人可以告诉我为什么我在这个简单的 C 程序中出现段错误吗?
在我结束第一个 for 循环后,我不断出现 seg 错误,而且我一生都不知道为什么。 我正在扫描的文件只有 18 行 18 个字符串。 我认为问题在于我分配称为 picks 的双指针的方式,但我不知道确切的原因。 我只是尝试扫描长度小于 15 个字符的字符串,所以我没有看到问题。有人可以帮忙吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 100
int main( int argc,char *argv[] )
{
char* string = malloc( 15*sizeof(char) );
char** picks = malloc(15*sizeof(char*));
FILE* pick_file = fopen( argv[l], "r" );
int num_picks;
for( num_picks=0 ; fgets( string, MAX_LENGTH, pick_file ) != NULL ; num_picks++ )
{
scanf( "%s", picks+num_picks );
}
//this is where i seg fault
int x;
for(x=0; x<num_picks;x++)
printf("s\n", picks+x);
}
I keep on getting seg faulted after I end my first for loop, and for the life of me I don't why.
The file I'm scanning is just 18 strings in 18 lines.
I thinks the problem is the way I'm mallocing the double pointer called picks, but I don't know exactly why.
I'm am only trying to scanf strings that are less than 15 chars long, so I don't see the problem. Can someone please help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 100
int main( int argc,char *argv[] )
{
char* string = malloc( 15*sizeof(char) );
char** picks = malloc(15*sizeof(char*));
FILE* pick_file = fopen( argv[l], "r" );
int num_picks;
for( num_picks=0 ; fgets( string, MAX_LENGTH, pick_file ) != NULL ; num_picks++ )
{
scanf( "%s", picks+num_picks );
}
//this is where i seg fault
int x;
for(x=0; x<num_picks;x++)
printf("s\n", picks+x);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
picks
是一个指向指针的指针:这意味着它指向的东西本身就是指针。当你这样做时:
你正在使
picks
指向一个由 15 个指针组成的块 - 就其本身而言,这很好(尽管如此,因为你想读取 18 行,这里确实需要 18,而不是 15)。这意味着picks
指向内存中的一个变量块,如下所示:如您所见,这 15 个
char *
指针现在未初始化 - 它们不指向任何东西。在为它们分配一些内存之前,您无法开始使用它们 - 您需要执行以下操作:现在,之后,内存布局如下所示:
...现在您有地方可以存储您想要读取的所有字符。
picks
is a pointer-to-a-pointer: that means that the things it points to, are themselves pointers.When you do this:
You are making
picks
point to a block of 15 pointers - which is fine as far as it goes (although, since you want to read in 18 lines, you really need 18 here instead of 15). This means thatpicks
points to a block of variables in memory like this:As you can see, those 15
char *
pointers are now unintialised - they don't point to anything. You can't start using them until you allocate some memory for those, too - you need to do something like this:Now, after that, the memory layout looks like this:
...and you now have places to store all those characters you want to read.
string
仅分配足够的内存来存储一个字符 (sizeof(char)
)。如果要存储更多字符,则需要将sizeof(char)
乘以要存储的字符串的大小,并为末尾的 null 值加一。而不是:
您想要执行此操作:
picks
数组的每个元素都需要足够大以容纳一个指针。string
is only getting allocated enough memory to store one character (sizeof(char)
). If you want to store more characters, you'll need to multiplysizeof(char)
by the size of the string you want to store, plus one for the null at the end.Instead of:
You want to do this:
Each element of the
picks
array needs to be big enough to hold a pointer.首先,在 C 中,字符串存储为字节(char)数组,并且必须进行分配。在这种情况下,用于读取文件的字符串应分配 MAX_LENGTH+1(+1 表示字符串终止符,\0)个字符:
这将为最大长度的字符串分配足够的内存:MAX_LENGTH。
另一个问题是指针数组
char **picks
没有分配来存储您期望读取的 18 个字符串:它必须分配给 15 个字符指针 (char *),这也必须在第一个循环中分配。
您还必须测试 malloc() 返回值,并且您可能想测试文件内容是否确实符合预期并且不包含更多行或长度超过 15 个字符的行。
另外 scanf() 读取标准输入,我将其替换为 sscanf(),并在第二个 printf() 中添加了缺少的“%”符号。
First of all, in C strings are stored as byte (char) arrays, and have to be allocated. In this situation, the string used to read he file should be allocated for MAX_LENGTH+1 (+1 for the string terminator, \0) chars:
This will allocate enough memory for a string of maximum length: MAX_LENGTH.
Another problem is that the array of pointers
char **picks
is not allocated to store the 18 strings you're expecting to read:It has to be allocated for 15 char pointers (char *), which also have to be allocated in the first loop.
You also have to test malloc() return value, and you may want to test if the file content really is as expected and does not contain more lines, or lines longer than 15 chars.
Also scanf() reads the standard input, I replaced it with sscanf(), and added the missing '%' sign in the second printf().
string
指向的位置仅分配了 一个 个字符的空间,但您尝试最多读取MAX_LENGTH
个字符;picks
指向的位置已分配但从未初始化。在将这 15 个(或 18 个)指针交给scanf
之前,您需要使它们实际指向某些东西本身。在这种情况下,实际上根本不需要动态分配 - 您可以使用数组执行您想要的操作:
string
is only allocated space for one char, but you try to read up toMAX_LENGTH
chars into it;picks
is only allocated space for 15char *
pointers, but you apparently want to store pointers to 18 strings there;picks
is allocated but never initialised. You need to make those 15 (or 18) pointers actually point to something themselves, before you hand them toscanf
.In this case, there is actually no need for dynamic allocation at all - you could do what you want with arrays:
是因为在该行:
for( num_picks=0 ; fgets( string, MAX_LENGTH, pick_file ) != NULL ; num_picks++ )
MAX_LENGTH
是 100,但您正在读入变量string
,它只能保存单个字符?Is it because in the line:
for( num_picks=0 ; fgets( string, MAX_LENGTH, pick_file ) != NULL ; num_picks++ )
MAX_LENGTH
is 100 but you're reading into the variablestring
, which can only hold an individual character?您正在为
picks
分配一个包含 15 个char*
的数组:现在
picks
有足够的空间来存储 15 个char*
,但您实际上从未在其中放置任何指向应包含读取字符的内存的指针。您需要为将使用
scanf
读取的这些字符串分配内存。目前,scanf 只是将数据写入 picks 中的指针(尚未初始化为指向任何有用的位置)所指向的位置。You are allocating an array of fifteen
char*
forpicks
:Now
picks
has enough space to store fifteenchar*
, but you never actually put any pointers inside that would point to memory that should contain the read characters.You need to allocate memory for these strings that will be read with
scanf
. At the momentscanf
just writes the data to wherever the pointers inpicks
(that have not been initialized to point anywhere useful) are pointing to.你在这里遇到了段错误。
scanf( "%s", picks+num_picks );
而是这样做,
问题是,你分配了
**pics
来容纳 15 个字符串,但你读取的字符串没有为这些字符串分配空间。确保您始终读取分配的指针。u r getting seg fault here.
scanf( "%s", picks+num_picks );
instead do this,
The problem is, u allocated
**pics
to hold 15 strings, but u read the strings without allocating the space for those strings. make sure u always read into allocated pointers.