繁体   English   中英

编写记忆集功能时出现问题

[英]Problems writing the memset function

我正在编写memset函数,而我的代码在下面,我遇到了问题

void* memsetFun(void* pointer, int c, int size) {

  if ( pointer != NULL && size > 0 ) {

    unsigned char* pChar =  pointer;


    int i = 0;

      for ( i = 0; i < size; ++i) {

      unsigned char temp = (unsigned char) c;

      *pChar++ = temp; // or pChar[i] = temp (they both don't work)

    }
  }  
    return pointer;


}

我还尝试了pChar [i] =我们想要的值,但仍然无法正常工作。 它给了我一些没有意义的垃圾编号。

我称之为:

memsetFun(address, num, size);
printf("value at %p is %d\n", address, *((int*) address));

我在哪里叫地址(我只是输入地址)

例如,如果要打印字符(c),它将打印为看起来像(值4)的奇怪字符

0 0
0 4

您的代码对我来说很好,这里的一些人评论说它可以在他们的系统上运行。

因此,显而易见的事情是调试它-这项技能将来会在很多时候派上用场:-)您应该现在就学习它。

运行以下代码会输出什么?

void* memsetFun(void* pointer, int c, int size) {
    printf("A %x %d %d\n", pointer, c, size);
    if ( pointer != NULL && size > 0 ) {
        printf("B\n");
        unsigned char* pChar =  pointer;
        int i = 0;
        for ( i = 0; i < size; ++i) {
            printf("C %d (%d)", i, *pChar);
            unsigned char temp = (unsigned char) c;
            *pChar++ = temp; // or pChar[i] = temp (they both don't work)
            printf(" -> (%d)", i, *(pChar-1));
        }
    }  
    printf("D\n");
    return pointer;
}

从输出中,应该清楚代码所采用的路径以及参数是什么(这将大大有助于调试过程)。

更新:

如果您要用零以外的任何内容填充内存块并使用此命令:

printf("value at %p is %d\n", address, *((int*) address));

打印出来,您得到奇怪的结果。

您基本上是在要求将这些字节中的一些解释为整数。 因此,例如,如果将其填充为0x02字节,并且具有4字节的整数类型,则将获得整数0x02020202 (33686018), 而不是您期望的0x02 如果要查看第一个字符值是什么,请使用:

printf("value at %p is %d\n", address, *((char*) address));

并根据您最新的问题更新:

例如,如果要打印字符(c),它将打印为看起来像(值4)的奇怪字符
0 0
0 4

如果那是单个字符,而您将其打印为字符,则可能根本没有错。 许多输出流将为您提供控制字符(在这种情况下为CTRL-D,ASCII代码4)。 如果改用ASCII代码0x30(48)填充它,则会看到字符'0'或ASCII 0x41(65)将给您'A'。

如前所述,您的函数可以正常工作。 这是一个完整的示例:

#include <assert.h>
#include <string.h>

void* memsetFun(void* pointer, int c, int size) {
    if ( pointer != NULL && size > 0 ) {
        unsigned char* pChar =  pointer;
        int i = 0;
        for ( i = 0; i < size; ++i) {
            unsigned char temp = (unsigned char) c;
            *pChar++ = temp; // or pChar[i] = temp (they both don't work)
        }
    }
    return pointer;
}

int main() {
    // Your memset
    char a[10];
    memsetFun(a, 'A', sizeof(a));

    // Uses system memset for verification
    char b[10];
    memset(b, 'A', sizeof(b));

    assert(sizeof(a) == sizeof(b));
    assert(memcmp(a, b, sizeof(b)) == 0);
    return 0;
}

return p; 防止编译:未定义p

一个较小的效率问题-实际上没有什么效果,因为任何好的编译器都会重新排列它,但是编码完美主义者不允许它保留temp的分配在循环内,但是每次都是相同的分配。 也就是说,可以在循环之前移动对temp的分配。

您返回p ,它没有定义/没有特别指向任何东西。 也许您是指pointer

该代码在逻辑上是正确的。 使用p => pointer更改,它可以正常工作。

弄清楚它到底“不起作用”的程度。 也许您不了解该怎么办?

您可能正在获取垃圾号码,因为您是将整数(4字节)转换为无符号字符(1字节),因此,如果c> 255或<0,则不会保留您期望的值。

你的功能,就是对我的作品。

我想你是在说错。 我这样称呼它

char a[100];
memsetFun(a, 0, sizeof a);
int b[100];
memsetFun(b, 0, sizeof b);

您如何称呼您的memsetFun()

编辑

int b[100];
memsetFun(b, 9, sizeof b);

由于int由4个字节组成(在我的系统上),每个值将设置为0x09090909151587081

我进行了测试,如果您的程序将5个元素的int向量的内存设置为值0x01。

这里的问题是,例如,您要在int向量(4个字节)中进行迭代,但是使用char指针算术(1个字节)对其进行迭代。 例如,如果要memset 0x01,则将在向量中的每个值写入此编号:00000001000000010000000100000001,使用原始memset给我相同的值。

那正是它应该做的。 您的功能运行正常。 值“ 0x4” 不是 ASCII字符“ 4”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM