use*_*448 0 c pointers memory-management
我想我也许终于在指针理解上有了一点突破,但我正在努力解决一个看似简单的问题,我想让一个指针指向与另一个指针相同的内存地址,例如:
\nchar* foo = "foo"; // memory address: 0x7ffdabc4dbf8\nchar* bar = "bar"; // memory address: 0x7ffdabc4dbf0\nRun Code Online (Sandbox Code Playgroud)\n如何将 foo 指向与 bar 相同的地址?我知道如何更改该值,例如:
\nfoo = bar; // foo is now "bar" but the memory address is the same as before\nRun Code Online (Sandbox Code Playgroud)\n我做了一些实验:
\n#include<stdio.h>\n#include<stdlib.h>\n#include<string.h>\n#include<errno.h>\n\nvoid print_info(char* string1, char* string2) {\n printf("Memory address of string1: %p\\n", &string1);\n printf("Memory address of string2: %p\\n", &string2);\n printf("Value of string1: %s\\n", string1);\n printf("Value of string2: %s\\n", string2);\n printf("\\n");\n}\n\nvoid change(char** ptr1, char** ptr2) {\n *ptr1 = *ptr2;\n}\n\nint main() {\n\n printf("Initial values: string1 = \\"foo\\" string2 = \\"bar\\"\\n\\n");\n\n char* string1 = "foo"; // Pointer to a string literal?\n char* string2 = "bar"; // Pointer to a string literal?\n\n print_info(string1, string2);\n\n // Modifying value, the pointer have the same memory address as before\n string1 = string2;\n printf("string1 = string2\\n\\n");\n\n print_info(string1, string2);\n\n string2 = "bas";\n printf("string2 = \\"bas\\"\\n\\n");\n\n print_info(string1, string2);\n\n change(&string1, &string2);\n printf("change(&string1, &string2)\\n\\n");\n\n print_info(string1, string2);\n\n char *ptr = string1;\n printf("char *ptr = string1\\n\\n");\n\n printf("Memory address of ptr: %p\\n", &ptr);\n printf("Value of ptr: %s\\n\\n", ptr);\n\n printf("Trying to change pointers directly:\\n\\n");\n\n printf("&string1 = &string2\\n");\n printf("GCC: error: lvalue required as left operand of assignment\\n\\n");\n //&string1 = &string2;\n\n printf("string1 = &string2\\n");\n printf("GCC: warning: assignment to \xe2\x80\x98char *\xe2\x80\x99 from incompatible pointer type \xe2\x80\x98char **\xe2\x80\x99\\n\\n");\n string1 = &string2;\n print_info(string1, string2);\n\n printf("&string1 = *string2\\n");\n printf("GCC: error: lvalue required as left operand of assignment\\n\\n");\n //&string1 = *string2;\n //print_info(string1, string2);\n\n printf("string1 = *string2\\n");\n printf("GCC: warning: assignment to \xe2\x80\x98char *\xe2\x80\x99 from \xe2\x80\x98char\xe2\x80\x99 makes pointer from integer without a cast\\n\\n");\n //string1 = *string2;\n //print_info(string1, string2);\n printf("Segmentation fault (core dumped)\\n\\n");\n\n printf("*string1 = &string2\\n");\n printf("GCC: warning: assignment to \xe2\x80\x98char\xe2\x80\x99 from \xe2\x80\x98char **\xe2\x80\x99 makes integer from pointer without a cast\\n\\n");\n *string1 = &string2;\n print_info(string1, string2);\n printf("Corruption?\\n");\n\n return EXIT_SUCCESS;\n}\nRun Code Online (Sandbox Code Playgroud)\n输出:
\nInitial values: string1 = "foo" string2 = "bar"\n\nMemory address of string1: 0x7fffc52760b8\nMemory address of string2: 0x7fffc52760b0\nValue of string1: foo\nValue of string2: bar\n\nstring1 = string2\n\nMemory address of string1: 0x7fffc52760b8\nMemory address of string2: 0x7fffc52760b0\nValue of string1: bar\nValue of string2: bar\n\nstring2 = "bas"\n\nMemory address of string1: 0x7fffc52760b8\nMemory address of string2: 0x7fffc52760b0\nValue of string1: bar\nValue of string2: bas\n\nchange(&string1, &string2)\n\nMemory address of string1: 0x7fffc52760b8\nMemory address of string2: 0x7fffc52760b0\nValue of string1: bas\nValue of string2: bas\n\nchar *ptr = string1\n\nMemory address of ptr: 0x7fffc52760d8\nValue of ptr: bas\n\nTrying to change pointers directly:\n\n&string1 = &string2\nGCC: error: lvalue required as left operand of assignment\n\nstring1 = &string2\nGCC: warning: assignment to \xe2\x80\x98char *\xe2\x80\x99 from incompatible pointer type \xe2\x80\x98char **\xe2\x80\x99\n\nMemory address of string1: 0x7fffc52760b8\nMemory address of string2: 0x7fffc52760b0\nValue of string1: \xef\xbf\xbd @\nValue of string2: bas\n\n&string1 = *string2\nGCC: error: lvalue required as left operand of assignment\n\nstring1 = *string2\nGCC: warning: assignment to \xe2\x80\x98char *\xe2\x80\x99 from \xe2\x80\x98char\xe2\x80\x99 makes pointer from integer without a cast\n\nSegmentation fault (core dumped)\n\n*string1 = &string2\nGCC: warning: assignment to \xe2\x80\x98char\xe2\x80\x99 from \xe2\x80\x98char **\xe2\x80\x99 makes integer from pointer without a cast\n\nMemory address of string1: 0x7fffc52760b8\nMemory address of string2: 0x7fffc52760b0\nValue of string1: \xef\xbf\xbd @\nValue of string2: \n\nCorruption?\nRun Code Online (Sandbox Code Playgroud)\n是否可以更改堆栈指针指向的地址?或者只能使用堆指针?(分配?)
\n定义之后
char* foo = "foo";
char* bar = "bar";
Run Code Online (Sandbox Code Playgroud)
你的记忆看起来像
+-----+ +--------+ | 富 | ---->| “富”| +-----+ +--------+ +-----+ +--------+ | 酒吧| ---->| “酒吧”| +-----+ +--------+
然后你做作业:
foo = bar;
Run Code Online (Sandbox Code Playgroud)
这导致内存看起来像这样:
+-----+ +--------+
| 富 | -\ | “富”|
+-----+ | +--------+
|
+-----+ | +--------+
| 酒吧| ->-->| “酒吧”|
+-----+ +--------+
现在,变量foo和bar都指向同一事物,但变量本身仍然是单独且不同的实体,并为它们分配了自己的内存。
另一方面,在 C 中,所有文字字符串(例如"foo")都不应该被修改。它们本质上是只读的。这就是为什么建议使用const char *变量来指向它们。这将允许编译器捕获通过指针变量修改文字字符串的尝试。