我正在從檔案中讀取。該檔案有以下內容:
One Fish Two 2 Red 2 Blue 2
Dr. Seuss
7 fish, 8 2, 8 2, 8 2,
Black 2, 3 2, Old 2, New 2.
This one has a little car.
6 6 6 6 6 star.
Say! What 5 lot of 12 there are.
Yes. Some 3 red, and some 4 blue.
6 3 old 6 6 4 new.
6 3 sad, 6 6 4 glad,
And 4 4 very, 1 bad.
Why 4 they 10 10 10 2 7?
0
我正在決議檔案并像現在一樣列印。dtok.c檔案,其中包含用于決議字串以及具有dlmfnt和dlmbck回傳值的函式。
dtok.c:
#include <string.h>
#include <malloc.h>
#include <assert.h>
char *dtok_r(char *s, const char *delim, char **save_ptr, char **dlmfnt, char *dlmbck) {
*dlmfnt = NULL;
*dlmbck = '\0';
char *end;
if (s == NULL)
s = *save_ptr;
if (*s == '\0') {
*save_ptr = s;
return NULL;
}
/* Scan the length of leading delimiter str. */
size_t dlmfnt_len = strspn(s, delim);
if (dlmfnt_len > 0) {
*dlmfnt = (char *)malloc((dlmfnt_len 1) * sizeof(char));
assert(dlmfnt != NULL && "NOT ENOUGH MEMORY FOR dlmfnt!!!");
strncpy(*dlmfnt, s, dlmfnt_len);
*(dlmfnt)[dlmfnt_len] = '\0';
}
s = dlmfnt_len;
if (*s == '\0') {
*save_ptr = s;
return NULL;
}
/* Find the end of the token. */
end = s strcspn(s, delim);
if (*end == '\0') {
*save_ptr = end;
return s;
}
/* Terminate the token and make *SAVE_PTR point past it and assign dlmbck */
if (*end != '\n') {
*dlmbck = *end;
}
*end = '\0';
*save_ptr = end 1;
return s;
}
這是我的main.c,它正在從檔案中讀取并決議并列印它:
/* Include standard library headers */
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>
#include <assert.h>
#include <stddef.h>
/* System Constants */
#define MAX_LINE_SIZE 512
int main(int argc, char **argv) {
assert(argc == 2 && \
"Program only operates with one file"
);
/* Open the file to decompress */
FILE *dcomp_file = fopen(argv[1], "r");
assert(dcomp_file != NULL && \
"Error opening file -->possibly missing<--"
);
/* Line Buffer for fgets */
char line_buff[MAX_LINE_SIZE];
/* dtok_r variable inits */
char *word_token, *save_ptr, dlmbck;
static const char *delim = " \n,.?!'\":;-"; /* Delimiter string for dtok_r */
/* Read line from file until end of file */
while (((fgets(line_buff, MAX_LINE_SIZE, dcomp_file) != NULL) && \
(strcmp(line_buff, "0\n") != 0))) {
save_ptr = line_buff;
if (strcmp(line_buff, "\n") != 0) {
char *dlmfnt = NULL;
while ((word_token = dtok_r(save_ptr, delim, &save_ptr, &dlmfnt, &dlmbck))) {
if (dlmfnt != NULL) {
printf("%s", dlmfnt);
//free(dlmfnt);
}
printf("%s", word_token);
putchar(dlmbck);
}
putchar('\n');
}
}
/* Close the decomp file */
int fclose_res = fclose(dcomp_file);
assert(fclose_res == 0);
/* Stop screen from disappearing until any character is pressed */
getchar();
return EXIT_SUCCESS;
}
這里發生的是當我取消注釋時free(dlmfnt),我得到錯誤的輸出。但我沒有釋放陣列我沒有得到錯誤的輸出。
我不免費使用時得到的正確輸出
One Fish Two 2 Red 2 Blue 2
Dr. Seuss
7 fish, 8 2, 8 2, 8 2,
Black 2, 3 2, Old 2, New 2.
This one has a little car.
6 6 6 6 6 star.
Say! What 5 lot of 12 there are.
Yes. Some 3 red, and some 4 blue.
6 3 old 6 6 4 new.
6 3 sad, 6 6 4 glad,
And 4 4 very, 1 bad.
Why 4 they 10 10 10 2 7?
當我使用免費的輸出時,我得到:
One Fish Two 2 Red 2 Blue 2
Dr. Seuss
7 fish, -d8 2, -d8 2, -d8 2,
Black 2, 3 2, -dOld 2, -dNew 2.
This one has a little car.
6 6 6 6 6 star.
Say! What 5 lot of 12 there are.
Yes. Some 3 red, -dand some 4 blue.
6 3 old 6 6 4 new.
6 3 sad, 6 6 4 glad,
And 4 4 very, 1 bad.
為什么會發生這種情況,我該如何解決?
uj5u.com熱心網友回復:
您的代碼中存在一些問題:
斷言
assert(dlmfnt != NULL && "NOT ENOUGH MEMORY FOR dlmfnt!!!")不正確:您不檢查記憶體分配失敗,但如果dlmfmt不為空。利用assert(*dlmfnt != NULL ...*(dlmfnt)[dlmfnt_len] = '\0'被決議為,如果不為零,*(dlmfnt[dlmfnt_len]) = '\0'則具有未定義的行為,可能會破壞記憶體,導致觀察到的行為。dlmfnt_len您可能想要這么簡單的代碼使用strndup():if (dlmfnt_len > 0) { *dlmfnt = strndup(s, dlmfnt_len); assert(*dlmfnt != NULL && "NOT ENOUGH MEMORY FOR dlmfnt!!!"); }當你
putchar(dlmbck)在最后一個單詞之后使用時,你輸出一個空位元組,它可能不會出現在終端上,但如果輸出被重定向到一個檔案,它會被存盤。你應該測驗:if (dlmbck) { putchar(dlmbck); }
uj5u.com熱心網友回復:
這就是 dtok 在采納@Chqrlie 和@John 的建議后的樣子
/* strtok that returns delimiters */
char * dtok_r (const char *restrict delim, char **restrict save_ptr, char **restrict dlmfnt, char *restrict dlmbck) {
*dlmfnt = NULL;
*dlmbck = '\0';
if (!*save_ptr) return NULL;
char *s = *save_ptr;
/* Scan the length of leading delimiter str */
size_t dlmfnt_len = strspn (s, delim);
if(dlmfnt_len > 0) {
/* strndup strings should be freed */
*dlmfnt = strndup(s, dlmfnt_len); /* Assign dlmfnt */
assert(*dlmfnt != NULL && "NOT ENOUGH MEMORY FOR dlmfnt!!!");
}
/* Start the token */
s =dlmfnt_len;
if(!*s) return *save_ptr = 0;
/* Find the end of the token. */
*save_ptr = s strcspn (s, delim);
/* Terminate the token and make *SAVE_PTR point past end of token and assign dlmbck */
if(**save_ptr !='\n') *dlmbck = **save_ptr;
if (**save_ptr) *(*save_ptr) = 0;
else *save_ptr = 0;
return s;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/514905.html
標籤:数组C细绳动态内存分配
