在共享内存中分配N size数组

时间:2018-01-29 13:02:14

标签: c memory memory-leaks shared-memory

我有一个结构

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

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

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

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

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))

2 个答案:

答案 0 :(得分:3)

你试过吗

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)从指向的字符串中复制最多n个字符,由src复制到dest。在src的长度小于n的长度的情况下,dest的余数将用空字节填充。

答案 1 :(得分:2)

这一行证明了最明显的问题:

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; } 。最终结果应该看起来像

$ rpm -ql zabbix-sender
/usr/bin/zabbix_sender
...