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

C语言二维数组平方数提取程序异常求助(动态内存/指针优化)

问题描述

编写了一个C语言程序,要求实现MAIN函数和两个FUNCTION,用于计算并打印30×25二维整数数组A中的平方数。但遇到以下问题:

  • 当设置cols=25且rows>25时,运行程序仅能显示function1输出的数组,无法展示降序排序数组和去重数组,且数组元素显示不全;
  • 当rows<25时程序正常运行。

推测需要为指针B分配足够大的内存空间,应该使用动态内存分配解决该问题,同时希望尽可能少使用指针。附上当前代码,请求技术帮助。

当前代码

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

int cols=25;
int rows=25;
int function1(int A[][cols],int size,int *B);
int function2(int *B,int size);

int main(){
    int i,j;
  int A[rows][cols];
  srand(time(NULL));
  for (i=0;i<rows;i++){
    for(j=0;j<cols;j++){
      A[i][j] = 1+(rand()%100);
    }
    }
   /*for (i=0;i<rows;i++){ 
     printf("\n");
    for(j=0;j<cols;j++){
      printf("%d  ",A[i][j]);
    } 
  }*/
  printf("\n");
  int *B;
  int size=function1(A,rows,B);
  printf("\n");
  function2(B,size);
  
  return 0;
}

int function1(int A[][cols],int size,int *B){  
  int i,j,k=0;
  printf("B: ");
     for(i=0;i<size;i++){
       for(j=0;j<cols;j++){
        for(int m=1;m<=10;m++){
          if(A[i][j]==m*m){
            B[k]=A[i][j];
            printf("%d ",B[k]);
            k++;
          }
        }    
         }
     }
  printf("\n");
  printf("There are %d squared numbers in that array",k);
  return k;
}

int function2(int *B,int size) {
  int i,j;
 for(i=0;i<size;i++){
   for(j=i+1;j<size;j++){
     if(B[j]>B[i]){
      int gecici=B[j];
      B[j]=B[i];
      B[i]=gecici;
    }
     }
 }
  printf("Descending sorted array is: ");
  for(int k=0;k<size;k++){
    printf("%d ",B[k]);    
  }
  printf("\n");
    int m,l,k;
    for(m=0;m<size;m++){
        for(l=m+1;l<size;l++){
            if(B[l]==B[m]){
                for(k=l;k<size-1;k++){
                    B[k]=B[k+1];
                }
                size--;
                l--; 
            } 
        }
    }
    printf("Arrays without duplicates: ");
    for(int a=0;a<size;a++){
        printf("%d ",B[a]);
    }
  return 0;
}
问题分析与修复方案

核心问题

当前代码中int *B;仅声明了指针但未分配内存空间,直接使用B[k]会触发未定义行为。rows较小时可能刚好占用栈上空闲内存未崩溃,但rows增大后,越界访问会破坏栈结构,导致后续函数无法正常执行。

修复步骤

1. 调整逻辑:先统计数量再分配内存

拆分原function1为两个函数,先统计数组中平方数的总数,再根据总数为B分配足够的动态内存,减少指针的滥用。

2. 修改后的完整代码

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

int cols = 25;
int rows = 30; // 测试rows>25的场景

// 统计数组中的平方数数量
int count_squares(int A[][cols], int size) {
    int i, j, count = 0;
    for (i = 0; i < size; i++) {
        for (j = 0; j < cols; j++) {
            int num = A[i][j];
            int root = sqrt(num);
            // 避免sqrt精度误差,直接验证平方结果
            if (root * root == num) {
                count++;
            }
        }
    }
    return count;
}

// 提取平方数到B数组并打印
void extract_squares(int A[][cols], int size, int *B) {
    int i, j, k = 0;
    printf("B: ");
    for (i = 0; i < size; i++) {
        for (j = 0; j < cols; j++) {
            int num = A[i][j];
            int root = sqrt(num);
            if (root * root == num) {
                B[k] = num;
                printf("%d ", B[k]);
                k++;
            }
        }
    }
    printf("\n");
    printf("There are %d squared numbers in that array\n", k);
}

// 对B数组进行降序排序和去重
void process_array(int *B, int size) {
    int i, j;
    // 冒泡降序排序
    for (i = 0; i < size; i++) {
        for (j = i + 1; j < size; j++) {
            if (B[j] > B[i]) {
                int temp = B[j];
                B[j] = B[i];
                B[i] = temp;
            }
        }
    }
    printf("Descending sorted array is: ");
    for (int k = 0; k < size; k++) {
        printf("%d ", B[k]);
    }
    printf("\n");
    // 去重逻辑
    int m, l, new_size = size;
    for (m = 0; m < new_size; m++) {
        for (l = m + 1; l < new_size; l++) {
            if (B[l] == B[m]) {
                // 移动元素覆盖重复项
                for (int k = l; k < new_size - 1; k++) {
                    B[k] = B[k + 1];
                }
                new_size--;
                l--; // 回退索引,避免跳过相邻重复项
            }
        }
    }
    printf("Arrays without duplicates: ");
    for (int a = 0; a < new_size; a++) {
        printf("%d ", B[a]);
    }
    printf("\n");
}

int main() {
    int i, j;
    int A[rows][cols];
    srand(time(NULL));
    // 填充随机数组
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            A[i][j] = 1 + (rand() % 100);
        }
    }

    // 1. 统计平方数数量
    int square_count = count_squares(A, rows);
    // 2. 动态分配内存
    int *B = (int *)malloc(square_count * sizeof(int));
    if (B == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }
    // 3. 提取平方数
    extract_squares(A, rows, B);
    // 4. 排序去重
    process_array(B, square_count);
    // 5. 释放动态内存,避免泄漏
    free(B);

    return 0;
}

3. 关键优化点

  • 拆分函数逻辑,先统计数量再分配内存,减少指针使用;
  • 使用malloc动态分配内存,确保B数组大小足够,彻底解决越界问题;
  • 优化平方数判断逻辑,避免循环1到10的冗余操作;
  • 添加内存分配失败的判断,增强程序健壮性;
  • 使用完动态内存后调用free,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:45:27