C语言 为什么当我将整数复制到新的动态数组中时,我会得到奇怪的值?



>我用 C 编写了一个函数,将所有素数从一个 int 数组复制到一个大小相同的新动态数组中。

这是函数:

int *cpy(int arr[], int size){
int *newArr = malloc(size * sizeof(int));
for (int i = 0; i < size; i++) {
if (isPrime(arr[i])) {
*(arr + i) = arr[i];
}
}
return newArr;
}

这是驱动程序代码

int arr[SIZE] = { 129, 73, 87, 2, 923, 6743, 983, 23 };
int *newArr = cpy(arr, SIZE);
printf("Question 4: ");
printIntArr(newArr);
free(newArr);

注意SIZE是我用来存储所有原型/宏的头文件中定义为 20 的宏

出于某种原因,我得到以下输出:

Question 4: 12261328 12255424 285212761 39925 33619971

我不明白我做错了什么。我对 C 比较陌生,所以我很抱歉犯了愚蠢的错误

编辑:我尝试了第一个评论解决方案,但我得到:

Question 4: 129 6684864 87 33150 923
int* cpy(int arr[], int size){
int* newArr = malloc(size * sizeof(int));
for (int i = 0; i < size; i++){
if (isPrime(arr[i])){
*(arr + i) = arr[i]; // <---------------- ? why you use arr here?
}
}
return newArr;
}

尝试:

int* cpy(int arr[], int size){
int* newArr = malloc(size * sizeof(int));
memset(newArr, 0, sizeof(size * sizeof(int)); // <----- initialize newArr
for (int i = 0; i < size; i++){
if (isPrime(arr[i])){
*(newArr + i) = arr[i]; // <--- ? I think you want to use newArr here
}
}
return newArr;
}

也许你也可以在newArr上添加一个内存集:

memset(newArr, 0, sizeof(size * sizeof(int));

memset 将使用默认值 (0( 初始化内存的某个区域 (newArr(,对于一定数量的字节(大小 * sizeof(int((,这样您就不会在那里找到"垃圾"(垃圾是非初始化值(

你有未定义的行为,因为cpy函数不会向目标数组写入任何内容:*(newArr + j) = arr[i];只是将arr[i]复制到自身。

还有一个问题:你只复制一些条目,所以你应该为目标数组使用单独的索引,并更改函数原型以返回存储在那里的元素数量。

这是一个修改版本:

#include <stdio.h>
#include <stdlib.h>
int isPrime(int n) {
if (n % 2 == 0)
return n == 2;
for (int i = 3;; i += 2) {
int quo = n / i;
int rem = n % i;
if (quo < i)
return 1;
if (rem == 0)
return 0;
}
}
void printIntArr(int *arr, int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("n");
}
int *filter_primes(int arr[], int size, int *nprimes) {
int *newArr = malloc(size * sizeof(int));
int j = 0;
for (int i = 0; i < size; i++) {
if (isPrime(arr[i])) {
newArr[j] = arr[i];
j++;
}
}
*nprimes = j;
return newArr;
}
int main() {
int arr[SIZE] = { 129, 73, 87, 2, 923, 6743, 983, 23 };
int n;
int *newArr = filter_primes(arr, SIZE, &n);
printf("Question 4: ");
printIntArr(newArr, n);
free(newArr);
return 0;
}

你需要在循环中建立第二个索引:

int* cpy(int arr[], int size){
int* newArr = malloc((size + 1) * sizeof(int));
for (int i = 0, j = 0; i < size; i++){
if (isPrime(arr[i])){
*(newArr + j) = arr[i];
j++;
}
}
newArr[j] = 0; // add a NULL at the end
return newArr;
}

如果你不这样做,你将有一个数组,内存中留下了未初始化的值

例:

输入: 1 3 6 9 13

输出: 1 3 72742729 92652729 13

原因:跳过了 6 和 9,并留下了垃圾值。

最新更新