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

C语言中以指针地址计算为循环条件的异常问题排查

C语言指针代码运行异常的原因分析

你提供的代码存在多个概念错误,直接导致运行异常,下面逐一拆解问题:

原始代码

#include <stdio.h>
#include <stdlib.h> // 原代码遗漏该头文件,`exit`和`malloc`依赖它

int main()
{
  
    int var1 = 7;
    int* ptr1 = &var1;
    int* ptrHold = ptr1;
    int memo = 0;

    ptr1 = (int*)malloc(7*sizeof(int));

    if(ptr1==NULL){
        printf("Memory couldn't be allocated...");
        exit(0);
    }
    else{
        printf("Memory allocated for ptr1 = %d\n",7*sizeof(int));
        printf("%d\n",(*(&ptr1+1)-ptr1));

        for(int i=0;memo<=(*(&ptr1+1)-ptr1)/sizeof(int);i++){
        *ptr1=i;
        memo += (int)(sizeof(int));
        ptr1++;
        }
    }

    ptr1 = ptrHold;

    for(int i=0;i<5;i++){
        printf("%d\n",ptr1[i]);
    }

    free(ptr1);
    return 0;
}

核心错误点

1. 错误通过*(&ptr1+1)-ptr1获取malloc内存大小

&ptr1是指向栈上指针变量ptr1的指针(类型为int**),&ptr1+1指向的是栈上ptr1变量之后的内存位置,和你用malloc在堆上分配的内存完全无关。这个计算出的差值是栈上相邻变量的地址差,属于无意义的垃圾值,根本不是你要的堆内存大小。

2. 循环条件逻辑完全混乱

你的循环条件memo<=(*(&ptr1+1)-ptr1)/sizeof(int)不成立:memo累加的是sizeof(int)(通常为4),而右边是垃圾值除以4,两者没有对应关系,会导致循环次数完全不可控,要么少赋值,要么越界访问堆内存,甚至破坏栈上的数据。

3. 错误释放栈内存

最后你把ptr1重新赋值为ptrHold(指向栈上的var1),然后调用free(ptr1)——free只能释放malloc/calloc/realloc在堆上分配的内存,释放栈内存属于未定义行为,会直接导致程序崩溃。

修正后的代码(符合预期输出)

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

int main()
{
    int var1 = 7;
    int* ptr1 = &var1;
    int* ptrHold = NULL; // 初始化为NULL,避免后续混淆
    int allocCount = 7; // 直接记录分配的int数量,这是你已知的参数

    ptr1 = (int*)malloc(allocCount * sizeof(int));
    ptrHold = ptr1; // 保存堆内存的起始地址,而非栈变量地址

    if(ptr1 == NULL){
        printf("Memory couldn't be allocated...");
        exit(0);
    }
    else{
        printf("Memory allocated for ptr1 = %d\n", allocCount * sizeof(int));
        
        // 直接用已知的分配数量控制循环,这是正确做法
        for(int i=0; i < allocCount; i++){
            ptr1[i] = i;
        }
    }

    // 用保存的堆起始地址遍历输出
    for(int i=0; i<5; i++){
        printf("%d\n", ptrHold[i]);
    }

    free(ptrHold); // 释放堆内存,符合`free`的使用要求
    return 0;
}

修正说明

  1. 新增allocCount变量记录malloc分配的int数量,直接用这个值控制循环——malloc分配的内存大小无法通过指针本身获取,必须自行记录。
  2. ptrHold改为保存堆内存的起始地址,避免和栈变量地址混淆。
  3. 移除无意义的*(&ptr1+1)-ptr1计算,改用数组下标ptr1[i]赋值,逻辑更清晰。
  4. 最后释放堆内存的起始地址ptrHold,符合内存管理规范。

预期输出

Memory allocated for ptr1 = 28
0
1
2
3
4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:48:23