�Marc 2024-03-06 12:29 采纳率: 100%
浏览 6
已结题

如何理解指针数组输出的各种地址

    int n=3;
    char *str[n];//注意指针未初始化(野指针),可能出现问题 
    for(int i=0; i<n;i++)
    {
            str[i]=(char*)malloc(sizeof(char));
            char ch=scanf("%s",str[i]);         
    }
    //显示输出 
    for(int i=0;i<n;i++){
        printf("str[%d]=%s\tstr[%d]=%p\t&str[%d]=%p\t*str[%d]=%p\n",i,str[i],i,str[i],i,&str[i],i,*str[i]);
    }
}

img

如何理解输出的各种地址

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-06 12:30
    关注

    引自免费微信小程序:皆我百晓生

    首先,让我们分析并详细解释代码中指针数组输出的各种地址:

    int n=3;
    char *str[n]; // 定义一个包含3个指向字符的指针数组
    
    // 分配内存给每个指针,并尝试读取字符串
    for(int i=0; i<n;i++)
    {
        str[i]=(char*)malloc(sizeof(char)); // 分配一个字节的内存,通常不足以存储整个字符串
        char ch=scanf("%s",str[i]);  // 这里试图读取一个字符串到分配的内存空间,但分配的空间太小,可能导致内存溢出
    }
    
    // 输出各种地址信息
    for(int i=0;i<n;i++){
        printf("str[%d]=%s\tstr[%d]=%p\t&str[%d]=%p\t*str[%d]=%p\n",i,str[i],i,str[i],i,&str[i],i,*str[i]);
    }
    

    对于输出的部分,有以下几点需要理解:

    1. str[i]

      • 这是在输出字符串内容。由于你只分配了一个字节给每个 str[i] 指向的内存区域,且没有为字符串末尾添加空字符 \0,所以这里的 %s 输出可能会导致未定义行为或者输出不完整的字符串。
    2. str[i]=%p

      • %p 是格式化字符串,用于输出指针变量的值,也就是每个 str[i] 指针所指向的内存地址。
    3. &str[i]

      • 这是在输出 str[i] 指针本身的地址。& 是取址运算符,它返回的是存放指针变量的地址,而不是指针所指向的地址。
    4. *str[i]=%p

      • 此处是错误的表达方式,因为 %p 需要一个指针作为参数,而 *str[i] 实际上是解引用操作,访问 str[i] 所指向的内存中的第一个字符。此处应该用 %c 来输出字符,而非 %p。但由于之前仅分配了一个字节,且未初始化,此部分输出同样具有未定义行为。

    修正后的代码应增加字符串所需的实际内存大小,并确保正确使用 %c 输出字符和避免未初始化的内存读取。同时,为了安全起见,应在使用完内存后释放它。

    修正后的示例(假设我们分配足以容纳一个小字符串的内存):

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int n = 3;
        char *str[n];
    
        for(int i = 0; i < n; i++) {
            str[i] = (char*)malloc(10 * sizeof(char)); // 分配足够存储短字符串的空间
            if (!str[i]) {
                perror("Failed to allocate memory");
                exit(EXIT_FAILURE);
            }
            scanf("%9s", str[i]); // 使用更安全的方式限制输入长度
        }
    
        // 输出正确的地址和字符串
        for(int i = 0; i < n; i++) {
            printf("str[%d]=%s\tstr[%d]=%p\t&str[%d]=%p\t*(str[%d])=%c\n", 
                   i, str[i], i, str[i], i, &str[i], i, *str[i]);
        }
    
        // 释放内存
        for(int i = 0; i < n; i++) {
            free(str[i]);
        }
    
        return 0;
    }
    

    现在,根据修正后的代码,输出将展示:

    • str[i]:存储在 str[i] 指向内存位置的字符串内容。
    • str[i]=%pstr[i] 指针指向的内存地址。
    • &str[i]=%pstr[i] 指针本身的地址。
    • *(str[i])=%cstr[i] 指向的第一个字符。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 3月14日
  • 已采纳回答 3月6日
  • 创建了问题 3月6日

悬赏问题

  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振