【问题标题】:Segmentation fault on typecasting void pointer to int将 void 指针类型转换为 int 时出现分段错误
【发布时间】:2012-02-07 14:49:41
【问题描述】:

看到这个帖子我写了以下内容:How do I convert from void * back to int

#include <iostream>
#include <stdlib.h>
using namespace std;

int main (int argc, char *argv[])
{
    void* port = (void*) atoi (argv[1]);

    cout << "\nvalue: \n" << atoi (argv[1]) << "\n";

    int h = *((int *)port);
    cout << h;
}

输出:

anisha@linux-dopx:~/> ./a.out 323

value: 
323
Segmentation fault
anisha@linux-dopx:~/>

海合会

我错过了什么?

【问题讨论】:

  • 我认为从 int 转换为 void* 根本不是故意的。由于位置 323 处未分配的内存,当您尝试取消引用 void* 时,仅此一项就会导致段错误。
  • @ksming 要更改哪一行?
  • 与您链接到的问题的不同之处在于,从 int* 转换为 void*,因此您应该转换回 int*。您执行从 int 到 void* 的转换,因此在这种情况下您应该转换回 int。但是,请尽量避免这种转换。
  • 如果您需要它来创建线程,请参阅我对 Luchian 的回答的评论,以完全避免强制转换。

标签: c++ segmentation-fault void void-pointers


【解决方案1】:

忽略中间转换的潜在问题,您从int 开始,最终将其视为int*。换句话说,您将atoi() 的结果视为一个地址,并尝试读取该地址处的内存。

【讨论】:

  • 但这void* port = atoi (argv[1]); 的结果是error: invalid conversion from ‘int’ to ‘void*’
【解决方案2】:

您尝试将 port 类型转换为 int 指针,但它不是指针。这是一个值。您正在使用 323 作为指针。如果你想得到一个int *,那么要么对argv[1]进行类型转换,要么是一个指向port的指针。端口也不应该被声明为void *,因为它在atoi() 中被处理为一个int,它可能应该只是一个int

【讨论】:

  • 我“需要”将端口声明为 void *。我想得到一个 int 作为答案。修正哪一行?
【解决方案3】:

您正在取消引用指向您不拥有的内存的指针,这是未定义的行为

【讨论】:

  • @AnishaKaul 这不是特定的行,而是逻辑错误。 void* port = (void*) atoi (argv[1]); 这会给你一个指向你不拥有的内存的指针,你试图取消引用。
  • 实际上,端口需要作为指向函数“pthread_create”的空指针传递。这就是我对它进行类型转换的原因。
  • @anisha:有关于这个的讨论,但我认为传递给 pthread_create 应该由动态内存完成: int* pArg = new int; *pArg = atoi(...); pthread_create(...pArg...);并删除新线程内的参数。它不是最像 C++ 的,但它尊重 void* 参数。
【解决方案4】:

我根据this SO answer做了如下调整:

#include <iostream>
#include <stdlib.h>
using namespace std;

int main (int argc, char *argv[])
{
    void *port = (void *) atoi(argv[1]);

    cout << "\nvalue: \n" << atoi (argv[1]) << "\n";

    int h = (char*)port - (char*)0;    
    cout << h;
}

结果:

$ g++ -Wall test.cpp
$ ./a.out 323

value: 
323
323

【讨论】:

  • 是的,它成功了,谢谢。你能解释一下吗? (char*)port - (char*)0;
  • 这对我来说似乎是未定义的行为:带有一个无处指向的指针和一个不需要指向地址 0x00000000 的空指针的算术...我可以看到它应该如何与最常见的编译器。
  • 我对此的想法可能是错误的,但我会把它扔在那里供其他人评论。减法运算符可以采用两个相同类型的指针。从char *port(这里实际上是int)的地址中减去“0”的地址,返回它们之间的1 字节char 元素的数量,该数量被隐式转换回int。 (尝试用int * 替换char *,你的答案h 应该除以sizeof(int),通常是四个字节。)
  • 请忽略这个答案,看看我的另一个答案。我认为我的新答案更有意义且更具可读性。
【解决方案5】:

更改下一行

void* port = (void*) atoi (argv[1]); 

int port = atoi (argv[1]); 

【讨论】:

  • 导致error: invalid conversion from ‘int’ to ‘void*’
  • 这是 c++ - 严格的类型转换。
【解决方案6】:

好的,请忽略我之前的回答。请执行以下操作,而不是 (char*)port - (char*)0

int h = *(int *)(&port);

你得到port的地址:

&port

将地址转换为int *

(int *)(&port)

然后解引用地址以取回您放入port的整数值:

*(int *)(&port)

【讨论】:

  • 这行得通。 :) 谢谢。在我原来的帖子中,我不知道我在做什么!对 SO 的快速回答让我很受宠若惊。 :D
  • 不用担心。这对我来说也很有教育意义。
【解决方案7】:

使用这个

int h = ((int)port);

因为您将 int 转换为 void*

现在将 void* 转换回 int by ((int )port)

所以使用int h = ((int )port);

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 1970-01-01
    • 2020-01-22
    • 2013-11-18
    • 1970-01-01
    • 2021-09-20
    • 2021-10-16
    • 1970-01-01
    相关资源
    最近更新 更多