c - c中的指针与数组有什么不同?

标签 c pointers

<分区>

我试着用谷歌搜索这个主题,但没有人能解释清楚。我尝试以下代码:

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

int main(int argc, char * argv[]){

    char * p1 = "dddddd";
    const char * p2 = "dddddd";
    char p3[] = "dddddd";
    char * p4 =(char*)malloc(sizeof("dddddd")+1);
    strcpy(p4, "dddddd");
    //*(p1+2) = 'b'; // test_1
    //Output >>  Bus error: 10

    // *(p2+2) = 'b'; // test_2
    // Output >> char_point.c:11:13: error: read-only variable is not assignable
    *(p3+2) = 'b'; // test_3
    // Output >>
    //d
    //dddddd
    //dddddd
    //ddbddd

    *(p4+2) = 'k'; // test_4
    // Output >>
    //d
    //dddddd
    //dddddd
    //ddbddd
    //ddkddd

    printf("%c\n", *(p1+2));
    printf("%s\n", p1);
    printf("%s\n", p2);
    printf("%s\n", p3);
    printf("%s\n", p4);

    return 0;
}

我尝试了 3 次测试,但只有 test_3test_4 可以通过。我知道 const char *p2 是只读的,因为它是一个常量值!但是我不知道为什么不能修改p1!它是内存的哪一部分布局?顺便说一句,我在我的 Mac 上用 GCC 编译它。

我尝试通过 gcc -S 将其编译为 dis-asm,我明白了。

.section    __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 13
.globl  _main
.p2align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq   %rbp
Lcfi0:
    .cfi_def_cfa_offset 16
Lcfi1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Lcfi2:
    .cfi_def_cfa_register %rbp
    subq    $48, %rsp
    movl    $8, %eax
    movl    %eax, %ecx
    leaq    L_.str(%rip), %rdx
    movl    $0, -4(%rbp)
    movl    %edi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    %rdx, -32(%rbp)
    movl    L_main.p3(%rip), %eax
    movl    %eax, -39(%rbp)
    movw    L_main.p3+4(%rip), %r8w
    movw    %r8w, -35(%rbp)
    movb    L_main.p3+6(%rip), %r9b
    movb    %r9b, -33(%rbp)
    movq    %rcx, %rdi
    callq   _malloc
    xorl    %r10d, %r10d
    movq    %rax, -48(%rbp)
    movl    %r10d, %eax
    addq    $48, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "dddddd"

L_main.p3:                              ## @main.p3
    .asciz  "dddddd"


.subsections_via_symbols

我想知道我声明的每个指针,它是哪个部分?

最佳答案

“为什么p1不能修改?”

粗略地说,p1 指向一个字符串文字,并且尝试修改字符串文字会导致 C 中的未定义行为。

更具体地说,根据 §6.4.5 6 of the C11 Standard ,字符串文字是:

used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char....

关于具有static 存储持续时间的对象,§5.1.2 1 states that

All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified.

“布局在内存的哪一段?”

但是,标准没有指定实现必须遵循的任何特定内存布局。

关于从字符串文字创建的 char 数组,标准所做的是 ( §6.4.5 7 ):

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

关于c - c中的指针与数组有什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48533248/

相关文章:

objective-c - 如何让 rand() 更有可能选择某些数字?

c - 我的用于删除C文件中注释的代码版本不起作用

c - TCP connect() 总是通过

c - 了解特定 C 指针定义的学校作业

c++ - 为什么这两种情况给出相同的结果?

c++ - 修改PIN中的申请说明

c++ - c/c++ 中的系统暂停

c++ - C++ 中的对象分配

c++ - 返回 vector 内对象的引用

c++ - 使用指向 <Employee> vector 的唯一指针 vector