我目前正在编写一个在共享内存中创建键值存储的程序。感兴趣的代码在kv_store_write()
函数中,但我将其余部分包含在上下文中。
内存最终将在各个进程之间共享,这些进程将读取值并将值写入同一内存空间。哈希函数用于提高搜索速度和确定存储位置。
我目前面临的挑战是以结构化方式存储键值对并访问该结构。我选择了如下定义的嵌套structs
。在使用mmap()
时,我将void指针转换为返回指向我定义的结构的指针的地址:Pod
。在kv_store_write()中,我尝试访问value
和key
我得到的编译错误并没有帮助我弄清楚出了什么问题。我是否适当地访问了我的结构元素?
我对何时使用->
和.
编辑: 为完整性我添加了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" );
}
//------------------------------------------------------------------
答案 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**
,即使它是在堆栈上声明的数组,这意味着一旦您返回,它的存储就会消失。