簡體   English   中英

C ++將void *轉換為int錯誤

[英]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'77+29 ,但'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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM