我有一个struct Chat
struct Chat
{
int m_FD;
int m_BindPort;
char m_NameLength;
char* m_Name;
char m_PeerCount;
char** m_PeerList;
} typedef Chat_t;
我正在使用此功能初始化它:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen+1));
strcpy(this->m_Name, name);
this->m_BindPort = bindPort;
this->m_PeerCount = peerCount;
this->m_PeerList = malloc(sizeof(char*) * peerCount);
for(int i=0; i<peerCount; i++)
{
this->m_PeerList[i] = malloc(sizeof(char) * 16); // enough for xxx.xxx.xxx.xxx\0
strcpy(this->m_PeerList[i], peerList[i]);
}
//Socket initialization for TCP connection...
//Commenting this out doesn't change anything so i'm hiding it for simplification
return 0;
}
之后我正在调用第二个函数
int chat_communicate(Chat_t* this)
{
printf("2\n");
fflush(stdout);
//Some stuff that doesn't matter because it isn't even called
return retVar;
}
像这样的
void main(void)
{
char* peerList[1];
char username[USERNAME_MAX_LEN];
int initRet;
int loopRet;
Chat_t chat;
peerList[0] = "192.168.2.2";
memset(username, 0, USERNAME_MAX_LEN);
printf("Please enter your user name: ");
scanf("%s", username);
username[USERNAME_MAX_LEN-1] = 0;
initRet = chat_init(&chat, strlen(username), username, 1234, 1, peerList);
printf("File Descriptor: %d\n", chat.m_FD);
printf("Binding Port: %d\n", chat.m_BindPort);
printf("Name Length: %d\n", chat.m_NameLength);
printf("Name: %s\n", chat.m_Name);
printf("Peer Count: %d\n", chat.m_PeerCount);
for(int i=0; i< chat.m_PeerCount; i++)
{
printf("Peer[%d]: %s\n", i, chat.m_PeerList[i]);
}
printf("1");
ret = chat_communicate(&chat);
//Even more Stuff that isn't even called
}
我的程序输出以下内容
File Descriptor: 3
Binding Port: 1234
Name Length: 4
Name: User
Peer Count: 1
Peer[0]: 192.168.2.2
1
Segmentation Fault
它编译时没有错误甚至是警告。
你也可以假设每个字符串都是空的 - 终止我用评论替换的东西并不复杂但只是显示太多。
结构中的每个值都在前面打印printf
,但是当每次引用传递这个结构时,应用程序崩溃。
我想知道的是为什么我会遇到此分段错误。因为它在调用函数时出现了,我认为它是某种布局问题,但我找不到类似的东西。
加成: 因为有些人无法相信我隐藏在“某些东西”后面的代码评论没有改变任何我想在此处声明的内容再次。此代码仅包含tcp套接字通信,仅执行读取操作。我也可以在没有这个代码的情况下重现上面提到的错误,所以请不要陷入困境。部件根本不会影响观察对象。
答案 0 :(得分:3)
在其他潜在问题中,
<!DOCTYPE html>
<html>
<body>
<ul id="list">
</ul>
<p id="demo" onClick="show()">Click ME</p>
</body>
</html>
显然是错误的。
this->m_PeerList = malloc(sizeof(char)*peerCount);
是m_PeerList
,但您只分配char **
个字节,只有当peerCount
指针是您系统上的一个字节时才有效可能的。
将其替换为
char *
请注意this->m_PeerList = malloc(peerCount * sizeof( *( this->m_peerList ) ) );
始终是一个 - 按定义。
答案 1 :(得分:2)
现在您已经发布了几乎完整的代码,我能够发现彼此相邻的两个问题:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen + 1)); // correct
//< this->m_Name = malloc(sizeof(char) * nameLen); // wrong
strcpy(this->m_Name, name); // correct
//< memcpy(this->m_Name, name, nameLen); // wrong
...
以//<
开头的行是您的原始代码:
在这里你没有分配足够的空间,你需要考虑NUL终结器:
this->m_Name = malloc(sizeof(char) * nameLen);
在这里你不复制NUL终止符:
memcpy(this->m_Name, name, nameLen);
你真的需要知道字符串在C中是如何工作的。
答案 2 :(得分:1)
您没有为this->m_Name
分配足够的内存。如果您希望它存储名称的以null结尾的字符串,那么它应该不止于此。
那,或者我们需要有关peerList
的更多信息。
答案 3 :(得分:1)
为什么不自己调试呢。如果使用GCC,请使用选项-g -O0
编译代码。然后使用gdb
:
gdb ./a.out
...
(gdb) r
如果崩溃了:
(gdb) bt
这将准确地说明它崩溃的地方。
更新:其他用户可能会发现您的代码存在潜在问题。但是,与内存分配相关的问题不会在调用函数chat_communicate
时使应用程序崩溃。这种行为可能有不同的原因,从堆栈溢出到不正确的编译。没有看到整个代码,很难说。最好的建议是考虑其他用户的评论意见并自行调试。