[英]Segmentation fault when converting char * to char **
我正在嘗試將句子(char *)拆分為單詞數組(char **)。 問題是我的函數有時不會返回有效的字符 **。
char **get_words(char *buffer, char delimiter)
{
char **words = malloc(sizeof(char *) * 4096);
for (int i = 0; i < 4096; i++)
words[i] = malloc(sizeof(char) * 4096);
int word_count = 0;
int l = 0;
for (int i = 0; buffer[i] != '\0' && buffer[i] != '\n'; i++, l++) {
if (buffer[i] == delimiter) {
words[word_count][l] = '\0';
word_count++;
l = -1;
}
else
words[word_count][l] = buffer[i];
}
words[word_count][l] = '\0';
return (words);
}
我首先像這樣使用它:
char *buffer = malloc(sizeof(char) * 50);
buffer = "/login test\n";
char **words = get_words(buffer, ' ');
printf("Words[0] = %s", words[0]);
它工作正常。
但是,當我這樣做時:
char **reply = get_words("502 Command doesn't exist.\n", ' ')
如果沒有分段錯誤,我什至無法打印回復[0][0](見下文)。 此外,我嘗試使用 valgrind 進行調試,但是當我使用它時,程序不會崩潰並且一切正常,所以我找不到問題所在。
printf("Reply[0][0] = %d\n", reply[0][0]);
printf("Reply[0][0] = %c\n", reply[0][0]);
編輯:這是一個可復制的例子。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
char **get_words(char *buffer, char delimiter)
{
printf("buffer = %s\n", buffer);
char **words = malloc(sizeof(char *) * 100);
if (words == NULL) {
printf("Malloc Error\n");
exit(84);
}
for (int i = 0; i < 100; i++) {
words[i] = malloc(sizeof(char) * 100);
if (words[i] == NULL) {
printf("Malloc Error\n");
exit(84);
}
}
int word_count = 0;
int l = 0;
for (int i = 0; buffer[i] != '\0' && buffer[i] != '\n'; i++, l++) {
if (buffer[i] == delimiter) {
words[word_count][l] = '\0';
word_count++;
l = -1;
}
else
words[word_count][l] = buffer[i];
}
words[word_count][l] = '\0';
return (words);
}
int main()
{
char *buffer = malloc(sizeof(char) * 100);
buffer = "hello world !\n";
char **words = get_words(buffer, ' ');
printf("words[0]= %s\n", words[0]);
free (buffer);
char **reply = get_words("Second call\n", ' ');
printf("reply[0] = %s\n", reply[0]);
}
如果您在學習編程方面需要幫助,可以嘗試使用靜態分析器。 這是一個執行代碼審查並發現可疑代碼片段的程序。 靜態分析器不能代替隊友執行的代碼審查。 然而,分析器補充了代碼審查並幫助在最早階段發現許多錯誤。
讓我們為問題所附的代碼示例運行PVS-Studio 分析器的在線版本。 第一個有趣且重要的警告是以下警告: V1031未聲明malloc
函數。 將數據傳入或傳出此函數可能會受到影響。
在沒有聲明malloc
函數的情況下,程序以一種奇怪的方式運行。 根據 C 語言,如果未聲明函數,則返回int
。 但實際上,它是一個指針。 你可以在這里找到為什么這是危險的。 讓我們通過添加#include <stdlib.h>
來解決這個問題。
現在分析器發出另一個警告——我們遇到了一個更嚴重的問題: 43:1:注意:V773 'buffer' 指針被賦值兩次,但沒有釋放內存。 內存泄漏是可能的。
問題出在以下代碼片段中:
char *buffer = malloc(sizeof(char) * 100);
buffer = "hello world !\n";
....
free (buffer);
指針值被覆蓋。 要將字符串復制到緩沖區,程序員應該使用特殊函數,例如strcpy
。 讓我們解決這個問題。
這是固定代碼。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
char **get_words(char *buffer, char delimiter)
{
printf("buffer = %s\n", buffer);
char **words = malloc(sizeof(char *) * 100);
if (words == NULL) {
printf("Malloc Error\n");
exit(84);
}
for (int i = 0; i < 100; i++) {
words[i] = malloc(sizeof(char) * 100);
if (words[i] == NULL) {
printf("Malloc Error\n");
exit(84);
}
}
int word_count = 0;
int l = 0;
for (int i = 0; buffer[i] != '\0' && buffer[i] != '\n'; i++, l++) {
if (buffer[i] == delimiter) {
words[word_count][l] = '\0';
word_count++;
l = -1;
}
else
words[word_count][l] = buffer[i];
}
words[word_count][l] = '\0';
return (words);
}
int main()
{
char *buffer = malloc(sizeof(char) * 100);
if (buffer == NULL)
exit(84);
strcpy(buffer, "hello world !\n");
char **words = get_words(buffer, ' ');
printf("words[0]= %s\n", words[0]);
free (buffer);
char **reply = get_words("Second call\n", ' ');
printf("reply[0] = %s\n", reply[0]);
}
我不能說這段代碼是完美和安全的,但它可以運行。 因此,使用靜態分析器查找錯誤,您可以改進您的學習過程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.