c - 如何分配适量的内存(c)
问题描述
我目前正在试验C
内存分配和共享内存。我需要帮助,代码是这样的:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "shared_memory.h"
#include "semaphore.h"
#include "errExit.h"
struct Node {
int ID;
char password[10];
struct Node *next;
};
key_t shmKeyServer = 131;
size_t size = (sizeof(struct Node)) * 100;
int main (int argc, char *argv[]) {
int shmidServer = alloc_shared_memory(shmKeyServer, size);
struct Node *node = (struct Node *)get_shared_memory(shmidServer, 0);
//fill all the structs
for(int i=0;i<100;i++){
node->ID = i;
sprintf(node->password, "%s%i", "campo num:", i);
node->next = node + sizeof(struct Node);
printf("you are on %i cicle \n", i);
node = node->next;
}
return 0;
}
功能alloc_shared_memory
在这里:
int alloc_shared_memory(key_t shmKey, size_t size) {
// get, or create, a shared memory segment
int shmid = shmget(shmKey, size, IPC_CREAT | S_IRUSR | S_IWUSR);
if (shmid == -1)
errExit("shmget failed");
return shmid;
}
get_shared_memory
:
void *get_shared_memory(int shmid, int shmflg) {
// attach the shared memory
void *ptr_sh = shmat(shmid, NULL, shmflg);
if (ptr_sh == (void *)-1)
errExit("shmat failed");
return ptr_sh;
}
问题是在第 8 条 cicle 之后。我得到分段错误。我认为问题在于内存分配或大小声明。
解决方案
问题是这条线:
node->next = node + sizeof(struct Node);
同样typeof(node)
,struct Node *
该语句node
按字节递增指针sizeof(struct Node) * sizeof(struct Node)
(参见 C 中的指针算术)。您希望按字节而不是节点递增node
指针。sizeof(struct Node)
sizeof(struct Node)
你要:
node->next = (char*)node + sizeof(struct Node);
// or better:
node->next = (void*)((uintptr_t)(void*)node + sizeof(struct Node));
node->next = (void*)((char*)(void*)node + sizeof(struct Node));
// or
node->next = node + 1;
node->next = &node[1];
这修复了段错误。
在行中:
sprintf(node->password, "%s%i", "campo num:", i);
发生未定义的行为。正在将"%s%i", "campo num:", i
12 个字节打印到node->password
指针中,它只有10
字节的内存:
campo num:1
对于以零字节结尾的字符串,为 11 个字符 + 1 个字节。同样对于更大的数字,10
sprintf
将写入 13 个字节。最好使用snprintf
as insnprintf(node->password, sizeof(node->password)
来防止缓冲区溢出。你也可以sprintf
返回值int ret = sprintf(..); if (ret > sizeof(node->password)) { err(1, "Overflowed"); }
推荐阅读
- java - Spring Data Cassandra:InvalidQueryException:UUID 应为 16 或 0 字节 (20)
- sql - 消息 8114,级别 16,状态 5,第 1 行 - Excel 到 SQL 数据迁移
- python - HttpResponseRedirect 在 Django 中不起作用
- python - 如何在 pandas 中使用 .isin 和 groupby
- pivot-table - 在 agularjs 中呈现数据透视表结果时发生错误
- c# - SignedXml.LoadXml() 引发 CryptographicException
- html - 重叠时的 Ionic 3 音频处理
- javascript - 使用javascript输入数据同时计算表格单元格
- node.js - node_modules 解析详情
- swift - SKTextureAtlas 被第二个 SKTextureAtlas 的声明覆盖