-1

我尝试练习编写此函数的通用函数:

void *scramble(void *arr, int ElemSize, int n, int *indArr); 但是每当我使用调试器运行程序时,它会在原型线上崩溃,使用 F11(Step Into)我会看到以下内容:

1.

#else  /* WPRFLAG */
            __initenv = envp;
            mainret = main(argc, argv, envp);
#endif  /* WPRFLAG */

2.

if ( !managedapp )
    exit(mainret);

然后控制台消息说:The program '[8108] 1.exe: Native' has exited with code 0 (0x0).

这是我的程序(请忽略逻辑编码错误,因为我想自己解决):

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

typedef char BYTE;

void *scramble(void *arr, int ElemSize, int n, int *indArr);

void main()
{
    int indArr[5]={5,4,3,2,1};
    int numbers[5]={1,2,3,4,5};
    char letters[5]={'a','b','c','d','e'};

    int *newNum;
    char *newLet;

    newNum = (int*)scramble(numbers, sizeof(int), 5, indArr);
    newLet = (char*)scramble(letters, sizeof(char), 5, indArr);
}

void *scramble(void *arr, int ElemSize, int n, int *indArr)
{
    int i;
    BYTE *read, *write;
    void *res;

    res = malloc(ElemSize*n);

    write = (BYTE*)res;
    read = (BYTE*)arr;

    for (i = 0; i < n; i++)
    {
        memcpy(write + indArr[i]*ElemSize, read, ElemSize);
        read += ElemSize;
    }

    return res;
}
4

2 回答 2

0

如果你看这memcpy条线:

memcpy(write + indArr[i]*ElemSize, read, ElemSize);

indArr[0]if的目的地不正确inAddr[0] = 5。把内存想象成一个连续的块,指针write指向开头。添加5 * ElemSize到 write 会将其置于分配的内存范围之外。

 _______________________
|    |    |    |   |    | 1
 -----------------------
^- write                 ^- write + 5 * ElemSize
于 2013-09-17T17:08:44.440 回答
0

OP 使用的是基于 1 的索引,而不是基于 0 的索引。这导致第一个 memcpy 写入边界外。更改代码如下。

// int indArr[5]={5,4,3,2,1};
int indArr[5]={4,3,2,1,0};

[编辑]

与@Freddie & 我的进一步研究未能复制 OP 的问题。OP 发布的“崩溃”之后的 2 个步骤是正常退出之前的正常步骤。要么陈述的事情有问题,要么 OP 的调试器/编译器只是“知道”它不需要打扰那些讨厌的scramble()函数调用,并且可以早点回家到 Bill 的家。

于 2013-09-17T17:19:44.070 回答