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
相关产品推荐
相关产品推荐

