簡體   English   中英

C-將整個結構寫入共享內存的困難

[英]C - Difficulties writing whole struct to Shared Memory

我在將結構寫入共享內存時遇到問題,因為這樣做時,代碼僅寫入結構的第一部分。

這是我的數據結構:

struct shmData{
    char number[4];
    char description[1020];
};

這是我的代碼:

//Structure Pointer - placed on SHM
struct shmstruct *ptr;
char description_to_write[1024] = {0};
struct shmData *data_ptr;
data_ptr = (struct shmData*) description_to_write;

//Shared Memory init
create_shm(&ptr);
printf("Started\n");

//Define Offsets
//init_shm(ptr);

//#########################

//Check if number exist
    if (!(strcmp("NO SUCH CODE\0", get_description(ptr, 6)))) {
        //-> If not, get next offset (nput) where to write new data
//      sem_wait(&ptr->mutex);
//      long offset = ptr->msgoff[ptr->nput];
//      printf("OFFSET: %li\n", offset);
//      if (++(ptr->nput) > NMESG)
//          ptr->nput = 0; /* circular buffer */
//      sem_post(&ptr->mutex);
//      printf("Buffer: %s", argv[2]);

    snprintf(data_ptr->number, 4, "%s", "6");
    snprintf(data_ptr->description, 1020, "%s\n", argv[2]);

    printf("DATA: %s\n", data_ptr->number);
    printf("DATA: %s\n", data_ptr->description);

    printf("description_to_write: %i\n", description_to_write);

    //strcpy(&ptr->msgdata[offset], );
    //sem_post(&ptr->nstored);
    //printf("Wrote...\n\n");
} else {
    //-> Else get offset of this number and put data to it
}

我該怎么寫? 在上面的代碼中,我只是嘗試顯示描述數組,但我只得到了數字。

我需要將其寫入共享內存,如下所示:

Number(space)(space)(space)Description

共享內存轉儲看起來像:

00003b0: 3120 2020 496e 7075 7420 4572 726f 720a  1   Input Error.
00003c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00007b0: 3220 2020 4f75 7470 7574 2045 7272 6f72  2   Output Error
00007c0: 0a00 0000 0000 0000 0000 0000 0000 0000  ................
00007d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

從調試器:

description_to_write[0] char    54 '6'  
description_to_write[1] char    0 '\000'    
description_to_write[2] char    0 '\000'    
description_to_write[3] char    0 '\000'
description_to_write[4] char    83 'S'  
description_to_write[5] char    111 'o' 
description_to_write[6] char    109 'm' 
description_to_write[7] char    101 'e' 
description_to_write[8] char    84 'T'  
description_to_write[9] char    101 'e' 
description_to_write[10]char    120 'x' 
description_to_write[11]char    116 't' 
description_to_write[12]char    10 '\n' 

丑陋的解決方案:

int i = 0;
        while(i < 4){
            if(data_ptr->number[i] == '\000'){
                data_ptr->number[i] = 32;
            }
            i++;
        }

傳遞給snprintf的4指定要寫入的最大字符數。 沒有寫的數量。 snprtinf取消它確實寫入的字符數。 因此,您僅打印1個字符,其后留3個空值。

做就是了:

snprintf(data->number,4,"%s    ","6");

這樣,它將嘗試打印字符串,后跟4個空格,並最多打印4個字符。

您使用snprintf()然后將'\\ 0'字符重寫為空格的丑陋解決方案存在一些缺陷:

  • snprintf()永遠不會將數字寫入data_ptr->number[3] 對於長度超過3個字符的字符串,它將截斷並寫入'\\ 0',而不是在源字符串中復制第4個字符。

  • 除非你確信結構將零之前調用初始化snprintf()那么“\\ 0”,經過字符snprintf()被要求寫不會被任意設置snprintf() 在您發布的代碼中,這可能不是問題,但是面對分配和初始化data_ptr指向結構的更改時,它是脆弱的。

由於該字段很小,因此您可以考慮以下內容:

memset( data_ptr->number, ' ', sizeof(data_ptr->number));
memcpy( data_ptr->number, "6", strlen("6"));

這仍然有一個缺點,如果源字符串可能比字段大小長,則需要添加更多的邏輯。 另外,如果您要在一個或兩個以上的地方進行操作,則很容易成為復制/粘貼錯誤的來源。

這是一個經過嚴格測試的函數,您可以代替使用(盡管我承認我討厭這個名稱):

size_t str2mem_padded( char* dest, size_t dest_size, char const* src, char fill)
{
    size_t result = 0;

    while (dest_size && *src) {
        *dest++ = *src++;
        ++result;
        --dest_size;
    }
    while (dest_size) {
        *dest++ = fill;
        --dest_size;
    }

    return result; // returns number of chars copied from src so you 
                   //   can determine if there was truncation
}

在您的代碼中,您可以使用以下代碼代替對snprintf(data_ptr->number, 4, "%s", "6")的調用:

str2mem_padded( data_ptr->number, sizeof(data_ptr->number), "6", ' ');

哇-那比我想象的要多得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM