我目前正在試驗指標,我對我的代碼有幾個問題
附:這只是為了試驗我不會在任何代碼中使用它
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
struct obj
{
int* IntPtr;
obj()
{
IntPtr = new int[2];
IntPtr[0] = 123;
IntPtr[1] = 456;
}
};
int main()
{
obj MyStruct;
long long int* Adress = (long long int*) & MyStruct; //pointer to a struct
//change value in struct
*(long long int*)(*Adress sizeof(int)) = 789;
std::cout << "get value by pointer: " << (int)*(long long int*)(*Adress sizeof(int)) << std::endl; //std::cout crashes my program
printf("get value by pointer: %d\n", (int)*(long long int*)(*Adress sizeof(int)));
printf("get value from struct: %d\n", MyStruct.IntPtr[1]);
return 0;
}
為什么 std::cout 使我的程式崩潰?我不得不使用 printf 函式來解決這個問題
我可以從我的主函式中洗掉 IntPtr 嗎?類似的東西
delete[] (long long int*)*Adress;然后創建新的?喜歡:int* Itemp = new int[5]; *地址 = (long long int)Itemp;
編輯:這只是一個關于如何int* IntPrt在我不會使用其他方法strcut obj時訪問的實驗private:。
代碼甚至與delete[]和new作業的罰款對我的編譯器
謝謝大家的解釋
uj5u.com熱心網友回復:
即使您的代碼中的語法錯誤已修復,我懷疑您嘗試執行的操作的前提仍然存在根本性缺陷。獲取一個指標,將其轉換為表示記憶體地址的數字,將其移動到另一個物件上并以這種方式訪問??它,這在 C 中是不允許的。
允許編譯器并積極地基于程式從不做這樣的事情的假設來優化代碼。因此,即使如果程式出現,而這樣做是作業,它可以在與不同的編譯器,不同的版本相同的編譯器,或者在相同的編譯器不同的編譯設定編譯很好的突破。
那么這對我們程式員來說意味著什么呢?指標是記憶體地址并不意味著我們可以將它們視為記憶體地址(除了一些特定的例外)。
指標指向物件(提醒:即使是簡單的int也是物件)。指標指向記憶體的事實是一個實作細節;除非您一次操作一個位元組的底層存盤的原始位元組。
您必須將指標視為:
不指向物件,在這種情況下,您只能分配、復制或比較它。
指向一個物件,在這種情況下,您也可以使用
*或取消參考它->。在一個物件,它是一個陣列的一部分,在這一點,也可以使用指點
[]或指標運算(,-在同一陣列中,等...)訪問其它物件。
就這樣。
考慮到這一點,您的代碼應該如下所示。這主要是供參考。我知道這不是你想要做的。
struct obj
{
int* IntPtr;
obj()
{
IntPtr = new int[2];
IntPtr[0] = 123;
IntPtr[1] = 456;
}
~obj()
{
// Btw. If you have a new, ALWAYS have a delete, even in throwaway code.
delete IntPtr[];
}
};
int main()
{
obj MyStruct;
// Get a pointer to the struct
obj* Adress = &MyStruct;
// Change value in struct via the pointer
obj->IntPtr[1] = 789;
(*obj).IntPtr[1] = 789;
std::cout << "get value by pointer: " << obj->IntPtr[1] << std::endl;
printf("get value by pointer: %d\n", obj->IntPtr[1]);
printf("get value from struct: %d\n", obj.IntPtr[1]);
}
編輯:為了完整起見,這里的代碼可以滿足我的解釋:
#include <iostream>
#include <cstdint>
#include <cassert>
struct obj {
int IntData[2];
};
int main()
{
obj MyStruct;
// Get a number containing the memory address associated with MyStruct.
// std::uintptr_t is the integer type of the same size as a pointer
std::uintptr_t AdressOfMyStruct = (std::uintptr_t)&MyStruct;
std::cout << "MyStruct lives at: " << AdressOfMyStruct << std::endl;
// Do the same thing for IntData[1]
std::uintptr_t AdressOfIntData1 = (std::uintptr_t)&MyStruct.IntData[1];
std::cout << "MyStruct.IntData[1] lives at: " << AdressOfIntData1 << std::endl;
// recalculate the address of IntData1 as an offset from MyStruct
std::uintptr_t AdressOfIntData1Calculated = AdressOfMyStruct sizeof(int);
std::cout << "MyStruct.IntData[1] lives at (alt): " << AdressOfIntData1 << std::endl;
// Verify that IntData[1] is where we expect it to be.
assert( AdressOfIntData1Calculated == AdressOfIntData1 );
// ...Everything up to here is valid code...
// WARNING: this may looks like it works, but it is, in fact, Undefined Behavior.
int* PtrToIntData1 = reinterpret_cast<int*>(AdressOfIntData1);
*PtrToIntData1 = 789;
// WARNING: This is also undefined behavior.
std::cout << "get value by pointer: " << *PtrToIntData1 << std::endl;
// This is fine, obviously.
std::cout << "get value from struct: " << MyStruct.IntData[1] << std::endl;
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/342879.html
上一篇:結構指標未按預期保存字符陣列
下一篇:cpp中動態分配和普通指標的區別
