今天用同样的代码任务测评了5个知名AI,Mistral, Gemini, Chatgpt, Claude 3.5, Llama 3,下面是我的问题:
用Linux C语言写一个内存动态分配管理链表MemChain,链表由多个内存分配单元MemChainBlock组成。
在MemChain中设置每次分配内存的最小数量、最大能分配的总内存数量、所有的MemChainBlock已经使用的内存数量、MemChainBlock的个数,记录链表的第一个和最后一个MemChainBlock。
每个MemChainBlock能记录自己的内存大小和已经使用的内存数量。
五个AI的回答如下,先说测评的结论。
最好的是Mistral,两个struct的定义完美,动态内存的分配功能也完美,缺点是只会说英文。
其次是google的gemini,虽然内容被截断了最后一小部分,但功能上已经看到跟Mistral一样实现完整了,而且它还自作主张地实现了双链,虽然不是我想要的,但也可以接受。
接下来的chatgpt就差很多了,首先是struct的定义出现严重遗漏,然后是没能实现动态分配内存的功能。
最危险的是claude 3.5和Llama 3,他俩表现一样,struct定义上的严重遗漏跟chatgpt一样,没有提供内存指针,但是它却实现了动态内存分配的功能,而且它这个功能使用的内存是未经分配的危险区域,十分危险!因此还不如chatgpt的不作为,至少比较安全。
Sign inhttps://chat.mistral.ai/
Sure, here's a simple example of a C program that implements a dynamic memory allocation management linked list called `MemChain`. The `MemChain` consists of multiple memory allocation units called `MemChainBlock`.
In `MemChain`, we set the minimum amount of memory to allocate each time, the maximum total amount of memory that can be allocated, the total amount of memory used by all `MemChainBlock`s, and the number of `MemChainBlock`s. We also keep track of the first and last `MemChainBlock` in the linked list.
Each `MemChainBlock` can record its own memory size and the amount of memory used.
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct MemChainBlock {
void *memory; // Pointer to the memory block
size_t size; // Size of the memory block
size_t used; // Amount of memory used
struct MemChainBlock *next; // Pointer to the next block
} MemChainBlock;
typedef struct MemChain {
size_t min_alloc; // Minimum amount of memory to allocate each time
size_t max_alloc; // Maximum total amount of memory that can be allocated
size_t total_used; // Total amount of memory used by all blocks
size_t num_blocks; // Number of blocks
MemChainBlock *first; // Pointer to the first block
MemChainBlock *last; // Pointer to the last block
} MemChain;
// Initialize a new MemChain
void memchain_init(MemChain *chain, size_t min_alloc, size_t max_alloc) {
chain->min_alloc = min_alloc;
chain->max_alloc = max_alloc;
chain->total_used = 0;
chain->num_blocks = 0;
chain->first = NULL;
chain->last = NULL;
}
// Allocate memory from the MemChain
void *memchain_alloc(MemChain *chain, size_t size) {
// Find a block with enough free memory
MemChainBlock *block = chain->first;
while (block != NULL && block->used + size > block->size) {
block = block->next;
}
// If no such block is found, create a new one
if (block == NULL) {
size_t new_size = size > chain->min_alloc ? size : chain->min_alloc;
if (chain->total_used + new_size > chain->max_alloc) {
return NULL; // Out of memory
}
block = malloc(sizeof(MemChainBlock));
block->memory = malloc(new_size);
block->size = new_size;
block->used = 0;
block->next = NULL;
if (chain->first == NULL) {
chain->first = block;
} else {
chain->last->next = block;
}
chain->last = block;
chain->num_blocks++;
}
// Allocate the memory and update the block's used memory
void *ptr = (char *)block->memory + block->used;
block->used += size;
chain->total_used += size;
return ptr;
}
// Free memory from the MemChain
void memchain_free(MemChain *chain, void *ptr) {
// Find the block that contains the memory
MemChainBlock *block = chain->first;
while (block != NULL && (char *)block->memory + block->size <= ptr) {
block = block->next;
}
// If the memory is not in the chain, do nothing
if (block == NULL || (char *)block->memory > ptr) {
return;
}
// Free the memory and update the block's used memory
size_t offset = (char *)ptr - (char *)block->memory;
block->used -= offset;
chain->total_used -= offset;
}
```
This program provides three functions: `memchain_init()` to initialize a new `MemChain`, `memchain_alloc()` to allocate memory from the `MemChain`, and `memchain_free()` to free memory from the `MemChain`.
In `memchain_alloc()`, if no block has enough free memory, a new block is created. The size of the new block is the maximum of `size` and `min_alloc`, but not larger than the remaining total memory. If the remaining total memory is not enough, `NULL` is returned to indicate an out-of-memory error.
In `memchain_free()`, the memory is not actually freed, but the used memory of the block is decreased. This is because the actual memory blocks are managed by the `MemChain`, not the user of the `MemChain`. If you want to actually free the memory, you can add a `memchain_destroy()` function to free all the memory blocks and the `MemChainBlock` structures.
接着是gemini, 两个struct的定义也没问题,缺点是因为内容太长,被截断了,输出不完整,另外也是只会说英文。
#include <stdio.h>
#include <stdlib.h>
typedef struct MemChainBlock {
void *data; // Pointer to the allocated memory block
size_t size; // Size of the allocated memory block
size_t used_memory; // Amount of memory used in the block
struct MemChainBlock *prev; // Pointer to the previous block in the list
struct MemChainBlock *next; // Pointer to the next block in the list
} MemChainBlock;
typedef struct MemChain {
size_t min_allocation_size; // Minimum allocation size
size_t max_memory; // Maximum usable memory limit
size_t total_used_memory; // Total memory used by all allocation units
size_t block_count; // Number of MemChainBlocks in the list
MemChainBlock *head; // Pointer to the first block in the list
MemChainBlock *tail; // Pointer to the last block in the list
} MemChain;
// Initialize the MemChain
void init_memchain(MemChain *mc, size_t min_allocation_size, size_t max_memory) {
mc->min_allocation_size = min_allocation_size;
mc->max_memory = max_memory;
mc->total_used_memory = 0;
mc->block_count = 0;
mc->head = NULL;
mc->tail = NULL;
}
// Allocate memory from the MemChain
void *allocate_memory(MemChain *mc, size_t size) {
if (size < mc->min_allocation_size) {
size = mc->min_allocation_size; // Round up to minimum size
}
if (size > mc->max_memory) {
return NULL; // Exceeds maximum memory limit
}
if (mc->total_used_memory + size > mc->max_memory) {
return NULL; // Not enough available memory
}
// Find a suitable block (if any)
MemChainBlock *prev = NULL;
MemChainBlock *curr = mc->head;
while (curr != NULL && (curr->size < size || curr->used_memory + size > curr->size)) {
prev = curr;
curr = curr->next;
}
if (curr == NULL) { // No suitable block found, allocate a new one
// Allocate new block and set its data pointer to NULL
MemChainBlock *new_block = malloc(sizeof(MemChainBlock));
if (new_block == NULL) {
return NULL; // Memory allocation failed
}
new_block->data = NULL;
new_block->size = size;
new_block->used_memory = 0;
new_block->prev = NULL;
new_block->next = NULL;
// Allocate memory block for the requested size
void *data = malloc(size);
if (data == NULL) {
free(new_block); // Free block if data allocation fails
return NULL;
}
// Update memory usage and add the block to the list
new_block->data = data;
new_block->used_memory = size;
mc->total_used_memory += size;
mc->block_count++;
if (mc->head == NULL) { // First block
mc->head = new_block;
mc->tail = new_block;
} else { // Add to the end
mc->tail->next = new_block;
new_block->prev = mc->tail;
mc->tail = new_block;
}
return data;
} else { // Use the existing block
// Update memory usage
curr->used_memory += size;
mc->total_used_memory += size;
return curr->data;
}
}
// Free memory allocated by the MemChain
void free_memory(MemChain *mc, void *ptr) {
if (ptr == NULL) {
return;
}
// Find the block corresponding to the given pointer
MemChainBlock *curr = mc->head;
while (curr != NULL && curr->data != ptr) {
curr = curr
然后是chatgpt的,遗漏了MemChainBlock中的一个重要的指针,也没有实现动态分配内存的功能,在硬核实力上比不上Mistral和gemini;但它的中文支持很好。
为了实现一个基本的内存动态分配管理链表 `MemChain`,由多个内存分配单元 `MemChainBlock` 组成,以下是一个简单的示例代码。在这个示例中,我们定义了结构体 `MemChainBlock` 表示链表中的每个节点,以及结构体 `MemChain` 表示整个链表。
```c
#include <stdio.h>
#include <stdlib.h>
// 定义内存分配单元的结构体
typedef struct MemChainBlock {
size_t size; // MemChainBlock 的内存大小
size_t used; // MemChainBlock 已经使用的内存数量
struct MemChainBlock *next; // 下一个 MemChainBlock 节点
} MemChainBlock;
// 定义链表的结构体
typedef struct MemChain {
size_t min_allocation; // 每次分配内存的最小数量
size_t max_total_memory; // 最大能分配的总内存数量
size_t total_used_memory; // 所有 MemChainBlock 已经使用的内存数量
size_t block_count; // MemChainBlock 的个数
MemChainBlock *first; // 链表的第一个 MemChainBlock
MemChainBlock *last; // 链表的最后一个 MemChainBlock
} MemChain;
// 初始化一个新的 MemChain
MemChain* memchain_init(size_t min_allocation, size_t max_total_memory) {
MemChain *chain = (MemChain *)malloc(sizeof(MemChain));
if (chain == NULL) {
perror("Memory allocation failed");
return NULL;
}
chain->min_allocation = min_allocation;
chain->max_total_memory = max_total_memory;
chain->total_used_memory = 0;
chain->block_count = 0;
chain->first = NULL;
chain->last = NULL;
return chain;
}
// 添加一个新的 MemChainBlock 到 MemChain 中
void memchain_add_block(MemChain *chain, size_t size) {
MemChainBlock *block = (MemChainBlock *)malloc(sizeof(MemChainBlock));
if (block == NULL) {
perror("Memory allocation failed");
return;
}
block->size = size;
block->used = 0;
block->next = NULL;
if (chain->first == NULL) {
chain->first = block;
chain->last = block;
} else {
chain->last->next = block;
chain->last = block;
}
chain->block_count++;
}
// 释放整个 MemChain 以及其中的所有 MemChainBlock
void memchain_destroy(MemChain *chain) {
MemChainBlock *current = chain->first;
MemChainBlock *next;
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
free(chain);
}
int main() {
// 初始化一个 MemChain,设置最小分配和最大总内存
MemChain *chain = memchain_init(1024, 1024 * 1024); // 最小分配为 1KB,最大总内存为 1MB
// 添加一些 MemChainBlock,模拟内存分配
memchain_add_block(chain, 4096); // 添加一个大小为 4KB 的 MemChainBlock
memchain_add_block(chain, 8192); // 添加一个大小为 8KB 的 MemChainBlock
// 输出链表中的每个 MemChainBlock 的信息(大小和已使用内存)
MemChainBlock *current = chain->first;
while (current != NULL) {
printf("MemChainBlock size: %zu bytes, used: %zu bytes\n", current->size, current->used);
current = current->next;
}
// 销毁 MemChain,释放所有内存
memchain_destroy(chain);
return 0;
}
```
### 解释与说明:
1. **结构体定义**:
- `MemChainBlock` 结构体表示链表中的每个节点,包含 `size`(内存大小)、`used`(已使用内存)和 `next`(指向下一个节点的指针)。
- `MemChain` 结构体表示整个链表,包含 `min_allocation`(每次分配的最小内存)、`max_total_memory`(最大总内存)、`total_used_memory`(所有节点已使用的内存总量)、`block_count`(节点数量)、`first`(指向第一个节点的指针)和 `last`(指向最后一个节点的指针)。
2. **函数实现**:
- `memchain_init`:初始化一个新的 `MemChain` 结构体,并返回指向它的指针。
- `memchain_add_block`:向 `MemChain` 中添加一个新的 `MemChainBlock` 节点。
- `memchain_destroy`:释放整个 `MemChain` 结构体以及其中的所有 `MemChainBlock` 节点的内存。
3. **示例程序 `main` 函数**:
- 创建一个 `MemChain` 结构体,设置最小分配和最大总内存。
- 添加一些 `MemChainBlock` 节点,模拟内存分配过程。
- 遍历并输出每个 `MemChainBlock` 节点的大小和已使用内存。
- 最后销毁 `MemChain`,释放所有动态分配的内存。
此示例是一个基础的实现,可以根据具体需求进一步扩展和优化,例如添加内存分配和释放的功能,或者增加对内存碎片和性能的优化。
最后是claude 3.5, 与chatgpt一样,MemChainBlock中遗漏了重要的指针成员,更离谱的是,后面它却实现了内存动态使用的功能,而且是在胡乱操作未分配的内存,这比chatgpt的不作为就更危险了!
好的,我会为您编写一个符合要求的Linux C语言内存动态分配管理链表。以下是实现代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct MemChainBlock {
size_t size; // 该块的内存大小
size_t used; // 已使用的内存数量
struct MemChainBlock *next; // 指向下一个块的指针
} MemChainBlock;
typedef struct MemChain {
size_t min_alloc; // 每次分配内存的最小数量
size_t max_total; // 最大能分配的总内存数量
size_t total_used; // 所有MemChainBlock已经使用的内存数量
size_t block_count; // MemChainBlock的个数
MemChainBlock *first; // 链表的第一个MemChainBlock
MemChainBlock *last; // 链表的最后一个MemChainBlock
} MemChain;
// 初始化MemChain
MemChain* init_mem_chain(size_t min_alloc, size_t max_total) {
MemChain *chain = (MemChain*)malloc(sizeof(MemChain));
if (chain == NULL) {
return NULL;
}
chain->min_alloc = min_alloc;
chain->max_total = max_total;
chain->total_used = 0;
chain->block_count = 0;
chain->first = NULL;
chain->last = NULL;
return chain;
}
// 在MemChain中分配新的MemChainBlock
MemChainBlock* alloc_mem_block(MemChain *chain, size_t size) {
if (chain->total_used + size > chain->max_total) {
return NULL; // 超过最大内存限制
}
size_t alloc_size = size > chain->min_alloc ? size : chain->min_alloc;
MemChainBlock *block = (MemChainBlock*)malloc(sizeof(MemChainBlock));
if (block == NULL) {
return NULL;
}
block->size = alloc_size;
block->used = 0;
block->next = NULL;
if (chain->last == NULL) {
chain->first = chain->last = block;
} else {
chain->last->next = block;
chain->last = block;
}
chain->block_count++;
return block;
}
// 在MemChain中分配内存
void* mem_alloc(MemChain *chain, size_t size) {
MemChainBlock *block = chain->first;
while (block != NULL) {
if (block->size - block->used >= size) {
void *ptr = (void*)((uintptr_t)block + sizeof(MemChainBlock) + block->used);
block->used += size;
chain->total_used += size;
return ptr;
}
block = block->next;
}
// 没有足够的空间,分配新的块
block = alloc_mem_block(chain, size);
if (block == NULL) {
return NULL;
}
void *ptr = (void*)((uintptr_t)block + sizeof(MemChainBlock));
block->used = size;
chain->total_used += size;
return ptr;
}
// 释放MemChain
void free_mem_chain(MemChain *chain) {
MemChainBlock *block = chain->first;
while (block != NULL) {
MemChainBlock *next = block->next;
free(block);
block = next;
}
free(chain);
}
// 打印MemChain的状态
void print_mem_chain_status(MemChain *chain) {
printf("MemChain Status:\n");
printf("Min Alloc: %zu\n", chain->min_alloc);
printf("Max Total: %zu\n", chain->max_total);
printf("Total Used: %zu\n", chain->total_used);
printf("Block Count: %zu\n", chain->block_count);
MemChainBlock *block = chain->first;
int i = 0;
while (block != NULL) {
printf("Block %d: Size = %zu, Used = %zu\n", i++, block->size, block->used);
block = block->next;
}
}
```
这个实现包含了以下主要功能:
1. `MemChainBlock` 结构体:表示单个内存块,包含大小、已使用量和指向下一块的指针。
2. `MemChain` 结构体:表示整个内存链表,包含最小分配量、最大总量、已使用总量、块数量,以及指向第一个和最后一个块的指针。
3. `init_mem_chain` 函数:初始化 MemChain。
4. `alloc_mem_block` 函数:在 MemChain 中分配新的 MemChainBlock。
5. `mem_alloc` 函数:在 MemChain 中分配内存。
6. `free_mem_chain` 函数:释放整个 MemChain。
7. `print_mem_chain_status` 函数:打印 MemChain 的当前状态。
这个实现满足了您的所有要求,包括设置最小分配量、最大总量、记录已使用量和块数量,以及维护第一个和最后一个块的指针。每个 MemChainBlock 也能记录自己的大小和已使用量。
您是否需要我解释代码的某个特定部分,或者您想了解如何使用这个内存管理系统?
还有Meta(facebook)的AI叫Llama 3,表现和claude 3.5一样。
https://meta.ai
作者寄语
以上如有错漏之处,敬请大家指正。我是主修C/C++、Vue3,开发网站的程序员,我的联系方式:
微信:TobeBuda
Email/Paypal: jinmin.si@outlook.com
邀请您加入「社区资讯服务」创业微信群,共同探讨打造社区资讯服务的美好未来。
参考资料
chatgpt
gemini
mistral
claude
llama