【问题标题】:Allocate N size array inside a Shared memory在共享内存中分配 N 大小的数组
【发布时间】:2018-01-29 13:02:13
【问题描述】:

我有一个结构

struct {
int size;
char *data;
}tmp_buf;

现在我想为共享内存中的结构分配内存(mmap-ed 位置)

我的 main() 中有一个类型为“tmp_buf”的指针“tp” 当我尝试在“tp->data”位置使用 strncpy() 时,会出现分段错误。

我有大小为 (sizeof(struct tmp_buf) + length_of_data) 的 mmap 共享内存

This is the code i'm running:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/mman.h>

void * create_shared_memory(char *name, int size) {

    int *ptr;
    int ret;

    int fd = shm_open (name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);

    if (fd == -1) {
        perror ("shm_open error!");
        exit (1);
    }

    ret = ftruncate (fd, sizeof (size));

    if (ret == -1) {
         perror ("ftruncate error!");
         exit (2);
    }

    ptr = mmap(0, sizeof (size), PROT_READ | PROT_WRITE,  MAP_SHARED, fd, 0);

    if (ptr == MAP_FAILED) {
        perror ("shm-mmap error!");
        exit (3);
    }

return ptr;

}

typedef struct {
        int size;
        char *data;

}tmp_buf;

int main (int argc, char **argv)
{
        tmp_buf *buf_ptr;
    if(argc != 2)
    {
        perror("Error: Incorrect number of arguments passed\n");
        exit(EXIT_FAILURE);
    }

        int max_buffers = atoi(argv[1]);
        buf_ptr = (struct tmp_buf*)create_shared_memory("my_shm_buffer",sizeof(tmp_buf) + max_buffers*1024);
        printf("Shared Memory Location: %p\n", buf_ptr);
        printf("Shared Memory size: %d\n", buf_ptr->size);
        printf("Shared Memory data: %s\n", buf_ptr->data);
        buf_ptr->size =1;
        printf("Shared Memory size: %d\n", buf_ptr->size);
        printf("SIZEOF(int) =%d SIZEOF(char*) = %d\n",sizeof(int), sizeof(char*));
        printf("Shared Memory size address: %p\n", (void*)&(buf_ptr->size));
        printf("Shared Memory data address: %p\n", (void*)&(buf_ptr->data));
        strncpy(buf_ptr->data,"Hello\n", 6);
        printf("Shared Memory data: %s\n", buf_ptr->data);
        return 0;
}

我看到的输出是这样的:

Shared Memory Location: 0x7ffff7ff6000
Shared Memory size: 0
Shared Memory data: (null)
Shared Memory size: 1 (After t->size = 1)
Shared Memory size address: 0x7ffff7ff6000
Shared Memory data address: 0x7ffff7ff6008
Segmentation fault (core dumped) (After strncpy("Hello\n",tp->data, 6))

【问题讨论】:

    标签: c memory memory-leaks shared-memory


    【解决方案1】:

    你试过了吗

    strncpy(buf_ptr->data, "Hello\n\0", 7);
    

    您应该将 strncpy 与 (dest, src, len) 一起使用,而不是 (src, dest, len)

    C 库函数 char *strncpy(char *dest, const char *src, size_t n) 从 src 指向的字符串复制最多 n 个字符到 dest。如果 src 的长度小于 n 的长度,则 dest 的剩余部分将用空字节填充。

    【讨论】:

    • 不改变结果
    • strncpy 是一个不好的选择,因为它不会自动 NUL 终止字符串,除非它在指定的大小内找到它,在这个例子中它不会因为字符串是 7 个字节长,不是 6。
    【解决方案2】:

    最明显的问题体现在这一行:

    ret = ftruncate (fd, sizeof (size));
    

    sizeof(size) 不会太多,因为它将是sizeof(int) 给你的任何东西。要使其达到您想要的大小,您只需传入size,就像这样......

    ret = ftruncate (fd, size);
    

    然后你用这行重复同样的问题,它也应该有size而不是sizeof(size)

    ptr = mmap(0, sizeof (size), PROT_READ | PROT_WRITE,  MAP_SHARED, fd, 0);
    

    可能值得更改函数声明以使size 成为size_t 类型并让它返回tmp_buf *。转换返回的void * 不会自动导致它使用有效值填充buf_ptr。最终结果应该是这样的

    tmp_buf* create_shared_memory(char *name, size_t size) {
    
        tmp_buf *ptr;
        int ret;
    
        int fd = shm_open (name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    
        if (fd == -1) {
            perror ("shm_open error!");
            exit (1);
        }
    
        ret = ftruncate (fd, size);
    
        if (ret == -1) {
             perror ("ftruncate error!");
             exit (2);
        }
    
        ptr = mmap(0, size, PROT_READ | PROT_WRITE,  MAP_SHARED, fd, 0);
    
        if (ptr == MAP_FAILED) {
            perror ("shm-mmap error!");
            exit (3);
        }
        ptr->size = size;
        ptr->data = ((char *) ptr) + sizeof(ptr->size);
    
        return ptr;
    }
    

    【讨论】:

    • 我已将大小传递为 [sizeof(struct tmp_buf) + 数据长度],所以我认为这不是问题所在。我确定我在这里遗漏了一些愚蠢的东西
    • 您将正确的值传递给create_shared_memory,但没有正确使用它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多