用于说明动态分配内存运行时间有效的反例实验 【1】

从《The.C.Programming.Language.2Nd.Ed 》5.17题出发,写两个分别使用和不使用动态分配内存拷贝字符串的程序。默认getline函数使用了malloc动态分配内存。

“Exercise 5−7. Rewrite readlines to store lines in an array supplied by main, rather than calling alloc to maintain storage. How much faster is the program?” 

exercise_5_7_with_alloc.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINES 1000
#define MAXLEN 1000

int readline(char *lineptr[], int maxlines);
void writelines(char *lineptr[], int nlines);

int main() {
    char *lines[MAXLINES];
    int nlines;

    nlines = readline(lines, MAXLINES);
    if (nlines >= 0) {
        writelines(lines, nlines);
        return 0;
    } else {
        printf("Error: input too big to handle\n");
        return 1;
    }
}

int readline(char *lineptr[], int maxlines) {
    int nlines = 0;
    char *line = NULL;
    size_t len = 0;

    while (nlines < maxlines && getline(&line, &len, stdin) != -1) {
        line[strcspn(line, "\n")] = '\0'; // Remove trailing newline
        lineptr[nlines] = line;
        line = NULL;
        nlines++;
    }

    free(line); // Free the memory allocated by getline
    return nlines;
}

void writelines(char *lineptr[], int nlines) {
    for (int i = 0; i < nlines; i++) {
        printf("%s\n", lineptr[i]);
    }
}

exercise_5_7_without_alloc.c 

#include <stdio.h>
#include <string.h>

#define MAXLINES 1000
#define MAXLEN 1000

int readline(char lineptr[][MAXLEN], int maxlines);
void writelines(char lineptr[][MAXLEN], int nlines);

int main() {
    char lines[MAXLINES][MAXLEN];
    int nlines;

    nlines = readline(lines, MAXLINES);
    if (nlines >= 0) {
        writelines(lines, nlines);
        return 0;
    } else {
        printf("Error: input too big to handle\n");
        return 1;
    }
}

int readline(char lineptr[][MAXLEN], int maxlines) {
    int nlines = 0;
    char line[MAXLEN];
    while (nlines < maxlines && fgets(line, MAXLEN, stdin) != NULL) {
        line[strcspn(line, "\n")] = '\0'; // Remove trailing newline
        strcpy(lineptr[nlines], line);
        nlines++;
    }
    return nlines;
}

void writelines(char lineptr[][MAXLEN], int nlines) {
    for (int i = 0; i < nlines; i++) {
        printf("%s\n", lineptr[i]);
    }
}

脚本生成测试文件:

#!/bin/bash

NUM_LINES=1000000  # 设置要生成的行数
OUTPUT_FILE=input_data.txt

# 生成随机文本行并写入文件
for ((i = 1; i <= NUM_LINES; i++)); do
    echo "Line $i: $(openssl rand -base64 32)" >> $OUTPUT_FILE
done

echo "Generated $NUM_LINES random lines to $OUTPUT_FILE"

清除内存和Cash准备实验环境:

fgetsgetline 都是用于从文件流中读取一行文本的函数,但它们有一些区别,主要是在以下几个方面:

  1. 接口和用法

    • fgets 是标准C库中的函数,用于从指定的文件流中读取一行文本。它的原型为:char *fgets(char *str, int n, FILE *stream);,其中 str 是一个指向字符数组的指针,n 是要读取的最大字符数(包括换行符和 null 终止符),stream 是要读取的文件流。
    • getline 是 POSIX 标准中定义的函数,用于从文件流中动态分配内存并读取一行文本。它的原型为:ssize_t getline(char **lineptr, size_t *n, FILE *stream);,其中 lineptr 是一个指向指针的指针,用于存储读取的文本内容,n 是指向 lineptr 所指向的缓冲区大小的指针,stream 是要读取的文件流。
  2. 内存分配

    • fgets 需要预先分配足够大小的缓冲区来存储读取的文本行。因此,你需要提前知道要读取的最大行长度,并分配相应大小的缓冲区。
    • getline 会根据需要动态分配内存来存储读取的文本行,因此不需要提前知道行的最大长度。它会根据需要自动调整分配的内存大小,确保足够存储整行文本。
  3. 行尾处理

    • fgets 会将换行符 \n 保留在读取的字符串中,并将其视为行的结束标志。
    • getline 会自动去除行尾的换行符,并将其从读取的字符串中移除。
  4. 错误处理

    • fgets 读取失败时返回 NULL,并且可以通过检查 feofferror 函数来确定是文件结束还是发生了错误。
    • getline 读取失败时返回 -1,并且会设置 errno 来指示发生了什么错误
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Emilin Amy

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值