从指向嵌套结构的指针访问元素

时间:2017-03-12 22:45:04

标签: c pointers struct shared-memory key-value-store

我目前正在编写一个在共享内存中创建键值存储的程序。感兴趣的代码在kv_store_write()函数中,但我将其余部分包含在上下文中。

内存最终将在各个进程之间共享,这些进程将读取值并将值写入同一内​​存空间。哈希函数用于提高搜索速度和确定存储位置。

我目前面临的挑战是以结构化方式存储键值对并访问该结构。我选择了如下定义的嵌套structs。在使用mmap()时,我将void指针转换为返回指向我定义的结构的指针的地址:Pod。在kv_store_write()中,我尝试访问valuekey

我得到的编译错误并没有帮助我弄清楚出了什么问题。我是否适当地访问了我的结构元素?

我对何时使用->.

感到困惑

编辑: 为完整性我添加了read函数。 以下是我得到的编译错误:

Assignement_2_1.c: In function ‘kv_store_read’:
Assignement_2_1.c:142:17: error: assignment to expression with array type
    valueInStore = memEthienne -> pod[hashedPod].value[podIndex];
                 ^
Assignement_2_1.c:143:11: warning: passing argument 1 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
    strcpy(value, valueInStore);// might be a problem with the way I am copying the value
           ^
In file included from Assignement_2_1.c:6:0:
/usr/include/string.h:125:14: note: expected ‘char * restrict’ but argument is of type ‘char **’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^
Assignement_2_1.c:143:18: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
    strcpy(value, valueInStore);// might be a problem with the way I am copying the value
                  ^
In file included from Assignement_2_1.c:6:0:
/usr/include/string.h:125:14: note: expected ‘const char * restrict’ but argument is of type ‘char **’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^
Assignement_2_1.c:144:11: warning: return from incompatible pointer type [-Wincompatible-pointer-types]
    return (value);
           ^
Assignement_2_1.c:144:11: warning: function returns address of local variable [-Wreturn-local-addr]
Assignement_2_1.c:149:1: error: expected declaration or statement at end of input
 }

这是代码

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

//----------------------------------------------------------------------

#define SIZE_OF_KEY 32
#define SIZE_OF_VALUE 256
#define NUMBER_OF_KEYVALUE_PAIRS 256
#define NUMBER_OF_PODS 256
#define SIZE_OF_INDEX 1
#define NUMBER_OF_INDEX 1
#define MEMORY_LENGTH (NUMBER_OF_PODS*NUMBER_OF_KEYVALUE_PAIRS*(SIZE_OF_VALUE + SIZE_OF_KEY + SIZE_OF_INDEX))

//-------------------------------------------------------------------
typedef char KEY[SIZE_OF_KEY];
typedef char VALUE[SIZE_OF_VALUE];

typedef struct{
    KEY key[NUMBER_OF_KEYVALUE_PAIRS];
    VALUE value[NUMBER_OF_KEYVALUE_PAIRS];
    int index; 
}keyValue;

typedef struct{
    keyValue pod[NUMBER_OF_PODS];
}Pod;

//typedef keyValue Pod[NUMBER_OF_PODS];


int kv_store_create(char *name);
int kv_delete_db();
int kv_store_write(char *key, char *value);
char *kv_store_read(char *key);
char **kv_store_read_all(char *key);

char *DATABASE_NAME = "memoryEthienne";

//-------------------------------------------------------------------
int main(){
    kv_store_create(DATABASE_NAME);
}
//-------------------------------------------------------------------
int hash_func(char *word){
    int hashAddress = 5381;
    for (int counter = 0; word[counter]!='\0'; counter++){
        hashAddress = ((hashAddress << 5) + hashAddress) + word[counter];
    }
    return hashAddress % NUMBER_OF_PODS < 0 ? -hashAddress % NUMBER_OF_PODS : hashAddress % NUMBER_OF_PODS;
}
//-------------------------------------------------------------------
int kv_store_create(char *name){
    int fd = shm_open(name, O_CREAT|O_RDWR, S_IRWXU); // shm_open return a file descriptor
    Pod* memEthienne = mmap(NULL, MEMORY_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // Makes the memory element sharable and useable in the process and returns a pointer to the adress of the memory for the particular process memory space

    ftruncate(fd, MEMORY_LENGTH); // This allocates the proper size to memory
    close(fd);
    DATABASE_NAME = name; // Could be a good idea to initialise the indexes in the creation function
}
//-------------------------------------------------------------------
int kv_store_write(char *key, char *value){

    if (strlen(key) > SIZE_OF_KEY){
        fprintf(stderr, "Please enter a valid length for the key\n" );
    }
    if (strlen(value) > SIZE_OF_VALUE){
        fprintf(stderr, "Please enter a valid length for the value\n" );
    }

    struct stat s;

    int fd = shm_open(DATABASE_NAME, O_RDWR, 0);
    if (fd < 0)
        printf("Error...opening shm\n");

    if (fstat(fd,&s) == -1){
        printf("Error fstat\n");
    }

    Pod* memEthienne = mmap(NULL, MEMORY_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // This returns an adress to shared memory in the and allocates it as a pointer to an array of structs
    close(fd);

    int hashedPod = hash_func(key);
    int podIndex = memEthienne -> pod[hashedPod].index;

       memset(&(memEthienne -> pod[hashedPod].key[podIndex]), 0, SIZE_OF_KEY);
       memset(&(memEthienne -> pod[hashedPod].value[podIndex]), 0, SIZE_OF_VALUE); //void *memset(void *s, int c, size_t n);
       strncpy(memEthienne -> pod[hashedPod].key[podIndex], key, strlen(key)); // strncpy((har *dest, const char *src, size_t n)
       strncpy(memEthienne -> pod[hashedPod].value[podIndex], value, strlen(value));
       if (podIndex < 255){
            (memEthienne -> pod[hashedPod].index)++;
        }
        else
        {
            memEthienne -> pod[hashedPod].index = 0;    
        }
}

//-----------------------------------------------------------------
char *kv_store_read(char *key){ // This function returns a copy of the string currently stored at the location in memory associated with the key
// 1 - Check value entered makes sense
// 2 - Hash the key
// 3 - Create a search counter
// 4 - Search the pod with the hashed key until the (current index -1) and return the associated value
// QUESTION : Am I opening the memory with the appropriate permissions
if (strlen(key) > SIZE_OF_KEY){
        fprintf(stderr, "Please enter a valid length for the key\n" );
struct stat s;
int fd = shm_open(DATABASE_NAME, O_RDWR, 0);
    if (fd < 0)
        printf("Error...opening shm\n");

    if (fstat(fd,&s) == -1)
        printf("Error fstat\n");

    Pod* memEthienne = mmap(NULL, MEMORY_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // This returns an adress to shared memory in the and allocagted it as a pointer to an array of structs
    close(fd);

    int hashedPod = hash_func(key);
    int podIndex = memEthienne -> pod[hashedPod].index;
    char* value[SIZE_OF_VALUE];
    char* valueInStore[SIZE_OF_VALUE];
    int searchIndex = 0;
    while (searchIndex < podIndex){

        if (strcmp((memEthienne -> pod[hashedPod].key[searchIndex]),key) == 0){
            valueInStore = memEthienne -> pod[hashedPod].value[podIndex];
            strcpy(value, valueInStore);// might be a problem with the way I am copying the value
            return (value);
        }
        searchIndex ++;
    }
    fprintf(stderr, "Unable to locate the requested key\n" );
}
//------------------------------------------------------------------

1 个答案:

答案 0 :(得分:0)

这一行

for(i in 1:length(sampledIDs)){ 
  if (3*i > nrow(dfW))
    dfW <- double_rowsize(dfW)
  dfW[(3*i-2):(3*i),] <- df[df$ID == sampledIDs[i],]
}

错误,因为 valueInStore = memEthienne -> pod[hashedPod].value[podIndex]; 是一个数组,而不是一个指针。 valueInStore会起作用,因为它是一个指针。

这一行

vlueInsStore[0]

错误,因为 strcpy(value, valueInStore); 是一个value指针数组,即它在函数参数的上下文中有类型char* - 我们说它“衰减”到一个指针。

此外,您尝试返回char**,即使它是在堆栈上声明的数组,这意味着一旦您返回,它的存储就会消失。