AI写代码测评报告,Mistral, Gemini, Chatgpt, Claude 3.5, Llama 3

今天用同样的代码任务测评了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 inicon-default.png?t=N7T8https://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的定义也没问题,缺点是因为内容太长,被截断了,输出不完整,另外也是只会说英文。

https://gemini.google.com/

#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;但它的中文支持很好。

https://chatgpt.com/

为了实现一个基本的内存动态分配管理链表 `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的不作为就更危险了!

ia.edualc \ Anthrop

好的,我会为您编写一个符合要求的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

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Mistral是一个开源的工作流引擎,用于管理复杂的、分布式的工作流任务。下面我将简要介绍Mistral的安装部署过程。 首先,我们需要准备以下基本要素: 1. 操作系统:Mistral可以运行在Linux和Windows操作系统上,但推荐使用Linux系统,如Ubuntu。 2. Python环境:Mistral是基于Python开发的,所以我们需要安装Python和相关的依赖。 3. 数据库:Mistral需要一个数据库来持久化存储任务和工作流的状态信息,常用的选择是MySQL、PostgreSQL等。 接下来,我们可以使用pip命令来安装Mistral和相关的依赖包: ``` $ pip install mistral[mongodb,mysql,postgresql,redis]==<version> ``` 其中`<version>`是Mistral的版本号,根据实际情况进行选择。 安装完成后,我们需要进行一些配置工作,包括: 1. 配置数据库:将数据库的连接信息配置到Mistral的配置文件中。 2. 配置认证:Mistral支持多种认证方式,可以选择适合自己的方式进行配置。 3. 配置消息队列:Mistral使用消息队列来处理任务,可以选择RabbitMQ、Kafka等消息队列工具,并将其配置到Mistral中。 完成上述配置后,我们可以启动Mistral引擎: ``` $ mistral-server --config-file <config_file_path> ``` 其中`<config_file_path>`是Mistral的配置文件路径。 随后,我们可以使用Mistral提供的API或者命令行工具来创建和管理工作流任务。 需要注意的是,Mistral还提供了一些可选的插件和扩展,用于支持额外的功能和集成其他系统。在实际部署过程中,我们可以根据需求进行选择和配置。 总结而言,Mistral的安装部署过程包括准备基本要素、安装依赖、配置环境、启动引擎等步骤,通过合理的配置和使用,可以有效地管理和执行复杂的工作流任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuzen

您的资助将帮助我创作更好的作品

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值