[英]c++ casting void* to int error
我是C / C ++的新手,我正在嘗試使用一個C庫來定義數據結構PDS並提供訪問數據的方法。
這是我用來訪問它的函數:
pdsGetNext (PDS *pds,char **pKey,PDStype *pT,size_t *pS,void **pD);
它基本上返回元素的鍵,元素的類型,元素的大小和元素的實際數據。 在文檔中, void **pD
的描述如下:“指向地址的指針,該地址獲取實際元素。”
我正在嘗試將數據轉換為“ PDStype”所指示的適當類型。 我在將數據轉換為整數時遇到問題,這是示例代碼:
char *key = NULL;
PDS_TYPE type;
size_t size;
void *data = NULL;
float f;
pdsRewind(myPDS);
while (pdsGetNext(myPDS, &key, &type, &size, &data) == PDS_ERR_NONE) {
switch (type) {
case PDS_TYPE::PDS_I:
// this is integer
printf("INT: %d\n", *((int*)data));
printf("INT PRINTED AS STRING: %s\n", (int*)data);
printf("INT AS STRING: %s\n", (char*)data);
break;
case PDS_TYPE::PDS_PCH:
//this is null terminated string
printf("STRING: %s\n", (char*)data);
break;
default:
break;
}
}
整數的實值是7,輸出如下:
INT: 55
INT PRINTED AS STRING: 7
INT AS STRING: 7
在我看來,如果我像void *ptr = (char*)malloc(sizeof(o))
這樣分配了void指針,那么我想成為的第一個void *ptr = (char*)malloc(sizeof(o))
就是“ 7”然后嘗試將其像*((int*)ptr)
一樣轉換為int
我的問題是:將其強制轉換為int時,我在做錯什么嗎? 據我了解,數據返回為void*
的原因是使人們能夠以這種方式使用轉換。
55是ASCII值“ 7”。 http://www.asciitable.com/
在C中:
int a = atoi(data);
在C ++ 11中:
int myint1 = std::stoi(data);
由於您使用C ++處理數據是無效的*,因此請執行reinterpret_cast<char*>(data);
像那樣:
int myint1 = std::stoi(reinterpret_cast<char*>(data));
在C中:
#include <stdio.h>
#include <stdlib.h>
int main()
{
// to get a void* like you
char *tmp = "7";
void *data = (void*)tmp;
// what is matter for you
int a = atoi((char*)data);
printf("a = %d\n", a);
return 0;
}
在C ++ 11中:
include <iostream>
int main()
{
// to get a void* with "7" like you we could get the same with a std::string
char *tmp = new char [1]();
tmp[0] = '7';
void * data = reinterpret_cast<void*>(tmp);
// what is matter for you
int a = std::atoi(reinterpret_cast<char*>(data));
std::cout << "a = " << a << std::endl;
return 0;
}
當您說“將char *轉換為int”時,您給出的是“定義不明確的規范”,因為char *的目的是為int提供完全不同的語義。
當您“強制”使用演員表時,您將以不同的語義重新解釋相同的位模式。 當您“轉換”一個值時,您正在將位模式更改為另一個保留盡可能語義的模式。
現在,字符文字(和字符串文字)是“可讀文本”: '7'
與7
, 7+2
為9
,但'7'+'2'
為'e'
。
那是因為+是整數運算,而'7'是53,'2'是48而101是'e'。
現在,您有一塊內存,其中放置了值“ 7”(這是與整數53對應的相同位模式:該內存本身與類型語義無關:僅包含00110101),其地址稱為void*
。
現在,由於printf
工作原理,%d需要int並使用數字語義,而%s需要char *並使用文本語義。
您作為第二個參數放置的所有內容都將根據這些規范進行讀取。
在第一種情況下,您將void*
用作它,因為它是一個int*
,您通過引用(通過unwary *
)獲得了一個對應於00110101的int值,即53,並將其提供給printf並將其視為數字,並將其轉換為顯示的文本(“ 53”)。
在第三種情況下,將void*
視為char*
,並將其提供給讀取它的printf(由於%s)作為“ char序列”,從而打印“ 7”。
在第二種情況下,您將一個int *並提供給printf它希望有一個char *的位置(因為%s,它會這樣處理),因此仍然為您提供“ 7”。
如果要將值"7"
(文本)轉換為數字7
(整數),則必須使用atoi
類的函數,並使用“%d”打印返回的值(現在是整數)。 使用%s會很麻煩,因為幾乎可以肯定7
被視為char *的地址超出了程序存儲空間
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.