![](/img/trans.png)
[英]How do I set a conditional breakpoint in gdb, when char* x points to a string whose value equals “hello”?
[英]How are pointers “variables whose values are an address” when we can do char *string = “string”?
我一直对指针的理解如下:
int x = 5;
int *y = &x;
printf("%d", *y);
x
访问该值。 y
,将其内存位置设置为x
的内存位置。 y
保存地址中的值。 但是,我可以同时执行char *string = "neato"
,它完全可以正常工作。 对我来说,这就像“创建一个字符指针,保存内存地址'neato'”。 这有什么意义?
此外,如果我设置了它,我会尝试将其设置为*string = "more neat"
但这会导致错误。 相反,我需要做string = "more neat"
。 直观上,第一次尝试看起来像是“将存储在字符串所保存的内存地址中的值更改为'更整洁'”,但这是行不通的。 第二个对我来说就像“对于'string'持有的内存地址,将其更改为'more neato'。这对我来说完全没有意义。
我有什么困惑? 如果要访问存储在指针上的值,我需要执行printf("%d", *pointer)
,那么如何不沿这些行设置它的值呢?
一元*
运算符具有两个不同(但相关)的目的。 在声明中 ,它表示该类型是指针类型,但并不意味着该指针已被取消引用。
当在表达式中使用时,它表示递减指针。 这就是为什么您的示例在声明的地方起作用的原因,但是在取消引用它时,您就不能分配(因为要分配的适当类型将是char,如果您可以以任何方式修改字符串文字)。
在声明之外执行此操作的等效方法如下:
const char *s = "hello"; /* initialize pointer value */
s = "goodbye"; /* assign to pointer value */
上面的初始化和分配是等效的。
"neato"
是const char[]
类型。 数组在适当的时候会衰减到指针,因此分配是一个指向另一个指针。
然后,您的指针应该指向const char
。 写入由字符串文字占据的内存位置会调用未定义的行为。 但是,这是有效的:
char str[] = "neato";
str[0] = 'p';
此外,如果我设置了它,我会尝试将其作为* string =“ more neat”
好吧,您有一个指向char的指针,因此分配没有任何意义(也是我上面所说的关于写字符串文字的内容。)
char *
和字符串“ neato”的基本类型都是char; 字符串文字只是字符数组,通常位于只读地址中。 “ n”必须位于地址中(下一个字符“ e”也必须如此)。 该地址存储在变量char *ptr
;
问题的第二部分是为什么*ptr = "more neat";
是无效的。
*var
取消引用地址-在这种情况下为1个字符的内存地址,该地址已经包含字符'n'。 您不能将新字符串文字的地址(可能用4或8个字节表示)都放在单个字符中; 也不能在其中放入9个字符和终止的ascii-零。
我们可以通过对16位(Big Endian)机器进行内存转储来研究此问题。
0FFE: .. .. // other variables, return addresses etc.
1000: F0 00 // The pointer "var" is located here
1002: // Top of stack
F000: "n" "e" "a" "t" "o" 00 // Address of constant string is F000
F006: "m" "o" "r" "e" ... // Address of next string is F006
*var
访问F000的单字节内存。 var
本身位于地址0000处,并且在本机中为两个字节,因为这里的地址为16位宽。 新的赋值之后, var="more neat"
; 内存转储为:
1000: F0 06 // Pointer holds a new address
例如,
char *ptr = "neato";
char arr[] = "neato";
完全不同。 ptr是指向字符串文字“ neato”的指针,编译器通常将字符串文字存储在只读存储器中。 因此,您不能更改字符串文字ptr指向的位置,但是可以更改ptr的值,即地址。
*ptr = "more neat"; // error, even if *ptr were writable, it should be a character
*ptr = 'b'; // error
ptr = "more neat"; // ok, you just create another string literal and ptr now points to it
第二个只是的缩写
char arr[] = {'n', 'e', 'a', 't', 'o', '\0'};
在这种情况下,您可以更改数组中的字符,但不能更改arr的地址(是的,这是一个数组)
*arr = 'b'; // ok
arr = "more neat" // error, the value of arr, namely the address of the array cannot be changed
初始化和赋值是不同的,即使它们看起来很相似,操作的含义也常常是不同的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.