You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改C语言栈指针指向的内存地址?

关于修改指针自身内存地址的疑问

我刚对指针有了一点理解突破,但遇到一个看似简单的问题:如何让一个指针指向另一个指针的内存地址?示例如下:

char* foo = "foo"; // memory address: 0x7ffdabc4dbf8
char* bar = "bar"; // memory address: 0x7ffdabc4dbf0

我知道如何修改指针指向的值,比如:

foo = bar; // foo is now "bar" but the memory address is the same as before

但这样操作后,foo自身的内存地址并未改变,只是指向了bar所指向的内容。我进行了相关实验,代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>

void print_info(char* string1, char* string2) {
    printf("Memory address of string1: %p\n", &string1);
    printf("Memory address of string2: %p\n", &string2);
    printf("Value of string1: %s\n", string1);
    printf("Value of string2: %s\n", string2);
    printf("\n");
}

void change(char** ptr1, char** ptr2) {
    *ptr1 = *ptr2;
}

int main() {

    printf("Initial values: string1 = \"foo\" string2 = \"bar\"\n\n");

    char* string1 = "foo"; // Pointer to a string literal?
    char* string2 = "bar"; // Pointer to a string literal?

    print_info(string1, string2);

    // Modifying value, the pointer have the same memory address as before
    string1 = string2;
    printf("string1 = string2\n\n");

    print_info(string1, string2);

    string2 = "bas";
    printf("string2 = \"bas\"\n\n");

    print_info(string1, string2);

    change(&string1, &string2);
    printf("change(&string1, &string2)\n\n");

    print_info(string1, string2);

    char *ptr = string1;
    printf("char *ptr = string1\n\n");

    printf("Memory address of ptr: %p\n", &ptr);
    printf("Value of ptr: %s\n\n", ptr);

    printf("Trying to change pointers directly:\n\n");

    printf("&string1 = &string2\n");
    printf("GCC: error: lvalue required as left operand of assignment\n\n");
    //&string1 = &string2;

    printf("string1 = &string2\n");
    printf("GCC: warning: assignment to ‘char *’ from incompatible pointer type ‘char **’\n\n");
    string1 = &string2;
    print_info(string1, string2);

    printf("&string1 = *string2\n");
    printf("GCC: error: lvalue required as left operand of assignment\n\n");
    //&string1 = *string2;
    //print_info(string1, string2);

    printf("string1 = *string2\n");
    printf("GCC: warning: assignment to ‘char *’ from ‘char’ makes pointer from integer without a cast\n\n");
    //string1 = *string2;
    //print_info(string1, string2);
    printf("Segmentation fault (core dumped)\n\n");

    printf("*string1 = &string2\n");
    printf("GCC: warning: assignment to ‘char’ from ‘char **’ makes integer from pointer without a cast\n\n");
    *string1 = &string2;
    print_info(string1, string2);
    printf("Corruption?\n");

    return EXIT_SUCCESS;
}

实验输出如下:

Initial values: string1 = "foo" string2 = "bar"

Memory address of string1: 0x7fffc52760b8
Memory address of string2: 0x7fffc52760b0
Value of string1: foo
Value of string2: bar

string1 = string2

Memory address of string1: 0x7fffc52760b8
Memory address of string2: 0x7fffc52760b0
Value of string1: bar
Value of string2: bar

string2 = "bas"

Memory address of string1: 0x7fffc52760b8
Memory address of string2: 0x7fffc52760b0
Value of string1: bar
Value of string2: bas

change(&string1, &string2)

Memory address of string1: 0x7fffc52760b8
Memory address of string2: 0x7fffc52760b0
Value of string1: bas
Value of string2: bas

char *ptr = string1

Memory address of ptr: 0x7fffc52760d8
Value of ptr: bas

Trying to change pointers directly:

&string1 = &string2
GCC: error: lvalue required as left operand of assignment

string1 = &string2
GCC: warning: assignment to ‘char *’ from incompatible pointer type ‘char **’

Memory address of string1: 0x7fffc52760b8
Memory address of string2: 0x7fffc52760b0
Value of string1: � @
Value of string2: bas

&string1 = *string2
GCC: error: lvalue required as left operand of assignment

string1 = *string2
GCC: warning: assignment to ‘char *’ from ‘char’ makes pointer from integer without a cast

Segmentation fault (core dumped)

*string1 = &string2
GCC: warning: assignment to ‘char’ from ‘char **’ makes integer from pointer without a cast

Memory address of string1: 0x7fffc52760b8
Memory address of string2: 0x7fffc52760b0
Value of string1: � @
Value of string2: 

Corruption?

现提出疑问:是否可以修改栈指针指向的内存地址?还是仅通过malloc分配的堆指针才能做到?


解答

首先明确核心概念:任何变量(包括指针变量)自身的内存地址,是由编译器和运行时环境在分配时确定的,一旦分配完成就无法修改——不管这个变量存储在栈上还是堆上。

你尝试的&string1 = &string2这类操作报错,本质是因为&string1是一个右值(它仅代表变量的地址本身,不是可被赋值的存储位置),C语言不允许给右值赋值。

你之前的困惑源于混淆了两个关键概念:

  1. 指针变量自身的内存地址:比如string1这个变量在栈上的存储地址(示例中的0x7fffc52760b8),这个地址是固定的,无法更改。
  2. 指针变量存储的指向地址:也就是指针变量的值,这个是可以修改的——比如你执行的string1 = string2,就是把string2存储的地址赋值给string1,让string1指向string2原本指向的内容。

不管是栈上的指针(比如你定义的char* string1)还是堆上的指针(比如char** heap_ptr = malloc(sizeof(char*))),它们自身的地址都无法修改。堆上的指针只是存储位置在堆,但它自身的地址同样固定,你能修改的只是它存储的指向地址。

你实验中的错误操作(比如string1 = &string2)属于类型不匹配,&string2是char**类型,赋值给char*类型的string1会导致指针指向非法内存区域,进而出现乱码或段错误,这本身就是非法操作,和修改指针自身地址无关。

总结

  • 所有变量(包括指针)自身的内存地址都无法修改,与存储位置是栈还是堆无关。
  • 你能修改的是指针变量存储的指向地址(即指针的值),这在栈指针和堆指针上都能实现。

内容的提问来源于stack exchange,提问作者user1359448

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 10:08:12