Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在数组外部写入后使用realloc写入错误的数组值_C - Fatal编程技术网

在数组外部写入后使用realloc写入错误的数组值

在数组外部写入后使用realloc写入错误的数组值,c,C,第一个循环的输出为1..20。 第二个循环的输出为1..30。 然后第三个循环从1..9开始运行,出于某种原因,它在第十个值处输出81 奇怪的是,如果我为第三个循环重新分配了11个元素,并打印了11个值,它会打印出1..11 我错过了什么 #include <stdio.h> int main() { unsigned int *P; P = malloc(20 * sizeof(int)); for (int i = 0; i < 20; i ++

第一个循环的输出为1..20。 第二个循环的输出为1..30。 然后第三个循环从1..9开始运行,出于某种原因,它在第十个值处输出81

奇怪的是,如果我为第三个循环重新分配了11个元素,并打印了11个值,它会打印出1..11

我错过了什么

#include <stdio.h>

int main() {
    unsigned int *P;
    P = malloc(20 * sizeof(int));

    for (int i = 0; i < 20; i ++) {
        (*(P + (i+1))) = (i+1);
        printf("(%d) Pointer address: %x | Pointer value %d \n", (i+1), (P + (i+1)), *(P + (i+1)));
    };

    P = realloc(P, 30 * sizeof(int));
    printf("------------------------------------------------------------ \n");
    printf("After reallocation... \n");
    printf("------------------------------------------------------------ \n");

    for (int i = 0; i < 30; i ++) {
        if (i > 19)
            (*(P + (i+1))) = (i+1);
        printf("(%d) Pointer address: %x | Pointer value %d \n", (i+1), (P + (i+1)), *(P + (i+1)));
    };


    P = realloc(P, 10 * sizeof(int));
    printf("------------------------------------------------------------ \n");
    printf("After deallocation... \n");
    printf("------------------------------------------------------------ \n");

    for (int i = 0; i < 10; i ++)
        printf("(%d) Pointer address: %x | Pointer value %d \n", (i+1), (P + (i+1)), *(P + (i+1)));
    return 0;
}

您的malloc/realloc太小,因此您在循环中访问的最后一个值可供编译器用于其他用途,因此到达循环末尾时的行为是未定义的,无论您在那里写入什么,在打印之前都可能会被覆盖,也可能不会被覆盖。在使用*P+i+1时,您需要向每一个添加+1,当i的范围为0..9时,您需要访问*P+9+1,它需要分配P+0,到P+10,它需要11个整数

例如,最后一个realloc应更改为:

p=reallocP,10*sizeofint

p=reallocP,10+1*sizeofint


更好的是,如果您没有像问题的评论者所指出的那样拥有所有+1,并根据需要调整所有其他代码,您将拥有更干净的代码。

数组索引从0开始,而不是从1开始。因此,可以使用*P+19访问数组的最后一个元素。当第一个循环中的i=19时,*P+i+1=i+1;写入*P+20,超出范围。越界访问内存是未定义的行为

删除代码中数组访问的所有+1,使其正常运行,即将所有p+i+1更改为p+i。此外,为了可读性,大多数程序员非常喜欢P[i]而不是*P+i。还有一些程序员更喜欢用&P[i]代替P+i——第i个元素的地址

另外,使用%x打印指针值是未定义的行为。%printf中的x需要其参数为unsigned int。将unsigned int*值传递给它是未定义的行为,这恰好在您的计算机上起作用,因为unsigned int的大小很可能与unsigned int*的大小相同。打印指针值的常用方法是使用%p printf说明符并将指针强制转换为void*。请注意,在大多数体系结构上,实际上并不需要强制转换为void*,因为所有指针的大小都相同,但不这样做在技术上是未定义的行为。如果仍要使用%x,则应将参数强制转换为正确的类型,如unsigneduintptr_tP+i

另外,您没有包括malloc和realloc函数的include。您至少应该看到编译器关于隐式声明的警告。这也是未定义的行为,因为隐式声明的函数与实际定义不匹配。隐式声明返回int,而malloc和realloc返回void*

记住错误处理。在无法分配内存的情况下,每个realloc和malloc都可以返回NULL

纠正这些错误后:

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

int main() {
    unsigned int *P;
    P = malloc(20 * sizeof(unsigned int));

    for (int i = 0; i < 20; i++) {
        P[i] = i + 1;
        printf("(%d) Pointer address: %p | Pointer value %d \n", 
            i + 1, (void*)(P + i), P[i]);
    };

    P = realloc(P, 30 * sizeof(unsigned int));
    printf("------------------------------------------------------------ \n");
    printf("After reallocation... \n");
    printf("------------------------------------------------------------ \n");

    for (int i = 0; i < 30; i ++) {
        if (i > 19) {
            P[i] = i + 1;
        }
        printf("(%d) Pointer address: %p | Pointer value %d \n", 
            i + 1, (void*)(P + i), P[i]);
    };


    P = realloc(P, 10 * sizeof(unsigned int));
    printf("------------------------------------------------------------ \n");
    printf("After deallocation... \n");
    printf("------------------------------------------------------------ \n");

    for (int i = 0; i < 10; i ++)
        printf("(%d) Pointer address: %p | Pointer value %d \n", 
            i + 1, (void*)(P + i), P[i]);
    return 0;
}

数组索引从0开始,而不是从1开始。。。从数组中删除所有+1。你为什么要写*P+i+1而不是简单的P[i+1]?@Barmar感觉不对。这是正常的方式。习惯它。当你有一个指向数组的指针时,把它当作一个数组来对待。P[i+1]感觉比*P+i+1更正确。后者极不自然。使用它可以传达某种程度的复杂程度,这对作者来说不是一种补充。
(1) Pointer address: 0x13c4260 | Pointer value 1 
(2) Pointer address: 0x13c4264 | Pointer value 2 
(3) Pointer address: 0x13c4268 | Pointer value 3 
(4) Pointer address: 0x13c426c | Pointer value 4 
(5) Pointer address: 0x13c4270 | Pointer value 5 
(6) Pointer address: 0x13c4274 | Pointer value 6 
(7) Pointer address: 0x13c4278 | Pointer value 7 
(8) Pointer address: 0x13c427c | Pointer value 8 
(9) Pointer address: 0x13c4280 | Pointer value 9 
(10) Pointer address: 0x13c4284 | Pointer value 10 
(11) Pointer address: 0x13c4288 | Pointer value 11 
(12) Pointer address: 0x13c428c | Pointer value 12 
(13) Pointer address: 0x13c4290 | Pointer value 13 
(14) Pointer address: 0x13c4294 | Pointer value 14 
(15) Pointer address: 0x13c4298 | Pointer value 15 
(16) Pointer address: 0x13c429c | Pointer value 16 
(17) Pointer address: 0x13c42a0 | Pointer value 17 
(18) Pointer address: 0x13c42a4 | Pointer value 18 
(19) Pointer address: 0x13c42a8 | Pointer value 19 
(20) Pointer address: 0x13c42ac | Pointer value 20 
------------------------------------------------------------ 
After reallocation... 
------------------------------------------------------------ 
(1) Pointer address: 0x13c52d0 | Pointer value 1 
(2) Pointer address: 0x13c52d4 | Pointer value 2 
(3) Pointer address: 0x13c52d8 | Pointer value 3 
(4) Pointer address: 0x13c52dc | Pointer value 4 
(5) Pointer address: 0x13c52e0 | Pointer value 5 
(6) Pointer address: 0x13c52e4 | Pointer value 6 
(7) Pointer address: 0x13c52e8 | Pointer value 7 
(8) Pointer address: 0x13c52ec | Pointer value 8 
(9) Pointer address: 0x13c52f0 | Pointer value 9 
(10) Pointer address: 0x13c52f4 | Pointer value 10 
(11) Pointer address: 0x13c52f8 | Pointer value 11 
(12) Pointer address: 0x13c52fc | Pointer value 12 
(13) Pointer address: 0x13c5300 | Pointer value 13 
(14) Pointer address: 0x13c5304 | Pointer value 14 
(15) Pointer address: 0x13c5308 | Pointer value 15 
(16) Pointer address: 0x13c530c | Pointer value 16 
(17) Pointer address: 0x13c5310 | Pointer value 17 
(18) Pointer address: 0x13c5314 | Pointer value 18 
(19) Pointer address: 0x13c5318 | Pointer value 19 
(20) Pointer address: 0x13c531c | Pointer value 20 
(21) Pointer address: 0x13c5320 | Pointer value 21 
(22) Pointer address: 0x13c5324 | Pointer value 22 
(23) Pointer address: 0x13c5328 | Pointer value 23 
(24) Pointer address: 0x13c532c | Pointer value 24 
(25) Pointer address: 0x13c5330 | Pointer value 25 
(26) Pointer address: 0x13c5334 | Pointer value 26 
(27) Pointer address: 0x13c5338 | Pointer value 27 
(28) Pointer address: 0x13c533c | Pointer value 28 
(29) Pointer address: 0x13c5340 | Pointer value 29 
(30) Pointer address: 0x13c5344 | Pointer value 30 
------------------------------------------------------------ 
After deallocation... 
------------------------------------------------------------ 
(1) Pointer address: 0x13c52d0 | Pointer value 1 
(2) Pointer address: 0x13c52d4 | Pointer value 2 
(3) Pointer address: 0x13c52d8 | Pointer value 3 
(4) Pointer address: 0x13c52dc | Pointer value 4 
(5) Pointer address: 0x13c52e0 | Pointer value 5 
(6) Pointer address: 0x13c52e4 | Pointer value 6 
(7) Pointer address: 0x13c52e8 | Pointer value 7 
(8) Pointer address: 0x13c52ec | Pointer value 8 
(9) Pointer address: 0x13c52f0 | Pointer value 9 
(10) Pointer address: 0x13c52f4 | Pointer value 10