【问题标题】:strtol() incorrectly returns 0strtol() 错误地返回 0
【发布时间】:2014-12-28 09:35:03
【问题描述】:

我正在做一个项目,由于某种原因,我无法让strtol()char * 转换为整数。我有这个代码:

int main(int argc, char *argv[]) {
    //socket initialization code...

    struct sockaddr_in addr;
    char *buffer;
    receivePacket(&sock, &buffer, &addr); //function i have written to receive a packet
    char *temp;
    int times = (int) strtol(buffer, &temp, 10);
}

当我运行它时,times 总是以 0 结束,并且 temp 返回垃圾:

(gdb) print buffer
$1 = 0xbefff648 "1"
(gdb) print times
$2 = 0
(gdb) print temp
$3 = 0xbefff648 "H\366\377\276(\207"

我不明白为什么 strtol 无法理解我给它的东西。

receivePacket:

void receivePacket(int *sock, char **buffer, long *tx, struct sockaddr_in *cliaddr) {
    //socket related code, initializations, etc.
    char temp[10] = { 0 };
    n = recvfrom(*sock, temp, 10, 0, (struct sockaddr *) &cliAddr, &clilen);
    *buffer = temp;
}

这是问题所在吗?谢谢。

【问题讨论】:

  • 您的调试器输出不可能是真实的。 buffertemp 都指向同一个地址,属于同一种类型,但返回的值不同。那是不可能的。请再次执行这些并提供真实的输出。
  • 建议:1)确保在从套接字读取之前为“缓冲区”分配空间(!!!),以及 2)检查“errno”。
  • 更新:您正在将缓冲区...读入局部变量。当函数终止时......缓冲区现在无效!!!!糟糕,糟糕,糟糕!
  • @Codo 这是真正的输出。我想这一定是因为receivePacket中的*buffer = temp

标签: c string sockets strtol


【解决方案1】:
void receivePacket(int *sock, char **buffer, long *tx, struct sockaddr_in *cliaddr) {
    //socket related code, initializations, etc.
    char temp[10] = { 0 };
    n = recvfrom(*sock, temp, 10, 0, (struct sockaddr *) &cliAddr, &clilen);
    *buffer = temp;
}

temp 是一个局部变量。当函数返回时它不再存在,留下*buffer 指向一些无效的地方。

【讨论】:

  • 哦,有道理。你能建议一种方法来修复我的代码吗?
  • main() 中的buffer 声明为大小合适的数组而不是指针,然后在receivePacket() 中使用strcpy()
  • 您有 3 个选项:(1) 按照@iharob 的建议执行并使用 strdup 分配缓冲区,或 (2) 将 temp 设为静态(放弃线程安全),或 (3)将调用代码中的缓冲区传递给receivePacket
【解决方案2】:

问题是

char temp[10] = {0};

是一个局部变量,它存在于receivePacket函数的栈帧中,尝试用strdup之类的方式复制它

*buffer = strdup(temp);

receivePacket函数返回temp中的数据时,将不存在记录器。

strtol之后别忘了free(buffer)

还有一件事,要么改变

char temp[10] = {0};

char temp[11] = {0};

n = recvfrom(*sock, temp, 10, 0, (struct sockaddr *) &cliAddr, &clilen);

n = recvfrom(*sock, temp, 9, 0, (struct sockaddr *) &cliAddr, &clilen);

否则您可能会覆盖尾随的'\0',在这种情况下strdup 将不起作用,strtol 也不起作用。

您还可以删除 temp[10] = {0}; 初始化,而是在 recvfrom 之后添加

temp[n] = '\0';

【讨论】:

  • 我其实不需要free(buffer),因为它不是动态分配的
  • @VaibhavAggarwal 如果你使用strdup,你会这样做。
  • 啊,我明白了,谢谢。我最终在调用receivePacket 之前定义了数组,并传入了一个指针以在recvfrom 中使用。
猜你喜欢
  • 2020-11-22
  • 2018-05-21
  • 2012-10-19
  • 1970-01-01
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
相关资源
最近更新 更多