为什么这个程序会崩溃,如果 SPLIT 在 4 和 7 之间
Why does this program crash, if SPLIT is between 4 and 7
我有一个任务,程序在大多数情况下都在运行,但是,如果我将 SPLIT 值设置在 4 到 7 之间,它就会崩溃(如果我更改 SIZE,则会在不同的值崩溃,但为了简单起见,让我们保持在 10)。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define SIZE 10
#define SPLIT 4
#define LOW 0
#define HIGH 10
void generateArray(int data[],int size,int low, int high){
srand(time(NULL));
for(int i=0;i<size;++i){
data[i]=rand()%(high-low+1)+low;
}
}
int splitData(int arraySize, int startArray[], int splitPoint, int **firstNewArray, int **secondNewArray){
if(arraySize < 1){
return -1;
}
if(splitPoint < 1 || (splitPoint >= arraySize)){
return -1;
}
if(*firstNewArray != NULL || *secondNewArray != NULL){
return -1;
}
*firstNewArray = malloc(splitPoint * sizeof(int));
*secondNewArray = malloc((arraySize - splitPoint) * sizeof(int));
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
(*firstNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}else{
(*secondNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}
}
return 0;
}
int main(){
int arraySize = SIZE ;
int *startArray = malloc(arraySize * sizeof(int));
generateArray(startArray,arraySize,LOW,HIGH);
int splitPoint = SPLIT;
int *firstNewArray = NULL;
int *secondNewArray = NULL;
int result;
result = splitData(arraySize, startArray, splitPoint, &firstNewArray, &secondNewArray);
if(result == 0){
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
printf("First array number %d is %d\n",i+1,firstNewArray[i]);
}else{
printf("Second array number %d is %d\n",i,secondNewArray[i]);
}
}
free(firstNewArray);
free(secondNewArray);
}
free(startArray);
return 0;
}
导致此行为的原因是什么?我该如何解决?任务是将 startArray
按值 SPLIT 拆分为 2 个新的动态数组,这将在函数 splitData
中创建,并且它们都可以在函数外部使用。
您的代码有两个问题
第一次显示结果时:
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
printf("First array number %d is %d\n",i+1,firstNewArray[i]);
}else{
printf("Second array number %d is %d\n",i,secondNewArray[i]);
}
}
如果数组大小太高或太低,这将无法正常工作,例如 splitPoint 为 9,这意味着 secondNewArray 大小为 1,但在此循环中,您访问的 secondNewArray[9]
应该为 0,您需要把循环改成这样
for(int i = 0; i < splitPoint; ++i){
printf("First array number %d is %d\n",i+1,firstNewArray[i]);
}
for(int i = 0; i < SIZE - splitPoint; ++i){
printf("Second array number %d is %d\n",i+splitPoint+1 ,secondNewArray[i]);
}
你的拆分函数有同样的问题:
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
(*firstNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}else{
(*secondNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}
}
在这种情况下,您也在访问数组大小之外的区域,假设拆分为 9,您将访问 secondNewArray[9] = startArray[9]
,而它应该是 secondNewArray[0] = startArray[9]
,要解决此问题,您需要在这里为每个数组使用不同的索引做同样的事情,代码应该是这样的:
int j = 0;
int k = 0;
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint) {
(*firstNewArray)[j] = startArray[i];
printf("%d\n",startArray[i]);
j++;
}
else {
(*secondNewArray)[k] = startArray[i];
printf("%d\n",startArray[i]);
k++;
}
}
仔细看看下面的标记线
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
(*firstNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}else{
(*secondNewArray)[i] = startArray[i]; // LOOK HERE
printf("%d\n",startArray[i]);
}
假设数组大小为10,分割点为4,则*secondNewArray
索引从0到5;但是,您试图分配元素 4 到 9,它们在数组的边界之外,导致 未定义的行为 。您需要调整 i
的值才能正确映射:
(*secondNewArray)[i - splitPoint] = startArray[i];
我有一个任务,程序在大多数情况下都在运行,但是,如果我将 SPLIT 值设置在 4 到 7 之间,它就会崩溃(如果我更改 SIZE,则会在不同的值崩溃,但为了简单起见,让我们保持在 10)。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define SIZE 10
#define SPLIT 4
#define LOW 0
#define HIGH 10
void generateArray(int data[],int size,int low, int high){
srand(time(NULL));
for(int i=0;i<size;++i){
data[i]=rand()%(high-low+1)+low;
}
}
int splitData(int arraySize, int startArray[], int splitPoint, int **firstNewArray, int **secondNewArray){
if(arraySize < 1){
return -1;
}
if(splitPoint < 1 || (splitPoint >= arraySize)){
return -1;
}
if(*firstNewArray != NULL || *secondNewArray != NULL){
return -1;
}
*firstNewArray = malloc(splitPoint * sizeof(int));
*secondNewArray = malloc((arraySize - splitPoint) * sizeof(int));
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
(*firstNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}else{
(*secondNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}
}
return 0;
}
int main(){
int arraySize = SIZE ;
int *startArray = malloc(arraySize * sizeof(int));
generateArray(startArray,arraySize,LOW,HIGH);
int splitPoint = SPLIT;
int *firstNewArray = NULL;
int *secondNewArray = NULL;
int result;
result = splitData(arraySize, startArray, splitPoint, &firstNewArray, &secondNewArray);
if(result == 0){
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
printf("First array number %d is %d\n",i+1,firstNewArray[i]);
}else{
printf("Second array number %d is %d\n",i,secondNewArray[i]);
}
}
free(firstNewArray);
free(secondNewArray);
}
free(startArray);
return 0;
}
导致此行为的原因是什么?我该如何解决?任务是将 startArray
按值 SPLIT 拆分为 2 个新的动态数组,这将在函数 splitData
中创建,并且它们都可以在函数外部使用。
您的代码有两个问题
第一次显示结果时:
for(int i = 0; i < arraySize; ++i){ if(i < splitPoint){ printf("First array number %d is %d\n",i+1,firstNewArray[i]); }else{ printf("Second array number %d is %d\n",i,secondNewArray[i]); } }
如果数组大小太高或太低,这将无法正常工作,例如 splitPoint 为 9,这意味着 secondNewArray 大小为 1,但在此循环中,您访问的 secondNewArray[9]
应该为 0,您需要把循环改成这样
for(int i = 0; i < splitPoint; ++i){
printf("First array number %d is %d\n",i+1,firstNewArray[i]);
}
for(int i = 0; i < SIZE - splitPoint; ++i){
printf("Second array number %d is %d\n",i+splitPoint+1 ,secondNewArray[i]);
}
你的拆分函数有同样的问题:
for(int i = 0; i < arraySize; ++i){ if(i < splitPoint){ (*firstNewArray)[i] = startArray[i]; printf("%d\n",startArray[i]); }else{ (*secondNewArray)[i] = startArray[i]; printf("%d\n",startArray[i]); } }
在这种情况下,您也在访问数组大小之外的区域,假设拆分为 9,您将访问 secondNewArray[9] = startArray[9]
,而它应该是 secondNewArray[0] = startArray[9]
,要解决此问题,您需要在这里为每个数组使用不同的索引做同样的事情,代码应该是这样的:
int j = 0;
int k = 0;
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint) {
(*firstNewArray)[j] = startArray[i];
printf("%d\n",startArray[i]);
j++;
}
else {
(*secondNewArray)[k] = startArray[i];
printf("%d\n",startArray[i]);
k++;
}
}
仔细看看下面的标记线
for(int i = 0; i < arraySize; ++i){
if(i < splitPoint){
(*firstNewArray)[i] = startArray[i];
printf("%d\n",startArray[i]);
}else{
(*secondNewArray)[i] = startArray[i]; // LOOK HERE
printf("%d\n",startArray[i]);
}
假设数组大小为10,分割点为4,则*secondNewArray
索引从0到5;但是,您试图分配元素 4 到 9,它们在数组的边界之外,导致 未定义的行为 。您需要调整 i
的值才能正确映射:
(*secondNewArray)[i - splitPoint] = startArray[i];