编写memset函数时出现问题

时间:2009-12-14 00:34:46

标签: c

我正在编写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

9 个答案:

答案 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), {{ 1}}正如你所料。如果要查看第一个字符值是什么,请使用:

0x02

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

  

例如,如果要打印字符(c),它会打印出类似于奇怪的字符(对于值4)
  0 0
  0 4

如果那是一个单一的角色并且你把它打印成一个角色,那么可能根本就没有错。许多输出流将为您提供控制字符(在本例中为CTRL-D,ASCII代码4)。如果你用ASCII码0x30(48)填充它,你会看到字符'0'或ASCII 0x41(65)会给你'A'。

答案 1 :(得分:1)

正如已经指出的那样,你的功能可以正常工作。这是一个完整的例子:

#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;
}

答案 2 :(得分:0)

return p;阻止编译:{{1​​}}未定义。

一个小的效率问题 - 在实践中它几乎没有效果,因为任何好的编译器都会重新排列它,但编码完美主义者不会允许它保留 - p的赋值在循环内,但它每次都是相同的任务。也就是说,可以在循环之前移动temp的赋值。

答案 3 :(得分:0)

您返回p,其未定义/未指向任何特定内容。也许你的意思是pointer

答案 4 :(得分:0)

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

澄清它是如何“不工作”的。也许你不明白它应该做什么?

答案 5 :(得分:0)

您可能正在获取垃圾编号,因为您正在从int(4个字节)转换为无符号字符(1个字节),因此如果c&gt; 255或&lt; 0你不会忘记你期望的值。

答案 6 :(得分: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

答案 7 :(得分:0)

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

这里的问题是你在int的向量中迭代(例如4个字节),但是使用char指针算法(1个字节)迭代它。例如,如果你想memset 0x01,你将在向量中为每个值写下这个数字:00000001000000010000000100000001 它使用原始的memset给我相同的值。

答案 8 :(得分:0)

这正是它应该做的事情。你的功能完美无缺。值“0x4” ASCII字符'4'。

相关问题