簡體   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