更改 C 堆栈指针地址(指向)

use*_*448 0 c pointers memory-management

我想我也许终于在指针理解上有了一点突破,但我正在努力解决一个看似简单的问题,我想让一个指针指向与另一个指针相同的内存地址,例如:

\n
char* foo = "foo"; // memory address: 0x7ffdabc4dbf8\nchar* bar = "bar"; // memory address: 0x7ffdabc4dbf0\n
Run Code Online (Sandbox Code Playgroud)\n

如何将 foo 指向与 bar 相同的地址?我知道如何更改该值,例如:

\n
foo = bar; // foo is now "bar" but the memory address is the same as before\n
Run 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}\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
Initial 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?\n
Run Code Online (Sandbox Code Playgroud)\n

是否可以更改堆栈指针指向的地址?或者只能使用堆指针?(分配?)

\n

Som*_*ude 5

定义之后

char* foo = "foo";
char* bar = "bar";
Run Code Online (Sandbox Code Playgroud)

你的记忆看起来像

+-----+ +--------+
| 富 | ---->| “富”|
+-----+ +--------+

+-----+ +--------+
| 酒吧| ---->| “酒吧”|
+-----+ +--------+

然后你做作业:

foo = bar;
Run Code Online (Sandbox Code Playgroud)

这导致内存看起来像这样:

+-----+ +--------+
| 富 | -\ | “富”|
+-----+ | +--------+
         |
+-----+ | +--------+
| 酒吧| ->-->| “酒吧”|
+-----+ +--------+

现在,变量foobar都指向同一事物,但变量本身仍然是单独且不同的实体,并为它们分配了自己的内存。


另一方面,在 C 中,所有文字字符串(例如"foo")都不应该被修改。它们本质上是只读的。这就是为什么建议使用const char *变量来指向它们。这将允许编译器捕获通过指针变量修改文字字符串的尝试。