c - char* 在循环的最后一次迭代中被破坏
问题描述
因此,我正在尝试构建一个string_split
函数来根据分隔符拆分 c 样式的字符串。
这是该函数的代码:
char** string_split(char* input, char delim)
{
char** split_strings = malloc(sizeof(char*));
char* charPtr;
size_t split_idx = 0;
int extend = 0;
for(charPtr = input; *charPtr != '\0'; ++charPtr)
{
if(*charPtr == delim || *(charPtr+1) == '\0')
{
if(*(charPtr+1) == '\0') extend = 1; //extend the range by one for the null byte at the end
char* string_element = calloc(1, sizeof(char));
for(size_t i = 0; input != charPtr+extend; ++input, ++i)
{
if(string_element[i] == '\0')
{
//allocate another char and add a null byte to the end
string_element = realloc(string_element, sizeof(char) * (sizeof(string_element)/sizeof(char) + 1));
string_element[i+1] = '\0';
}
string_element[i] = *input;
}
printf("string elem: %s\n", string_element);
split_strings[split_idx++] = string_element;
//allocate another c-string if we're not at the end of the input
split_strings = realloc(split_strings, sizeof(char*) *(sizeof(split_strings)/sizeof(char*) + 1));
//skip over the delimiter
input++;
extend = 0;
}
}
free(charPtr);
free(input);
return split_strings;
}
本质上,它的工作方式是有两个char*
,input
和charPtr
。 charPtr
从输入字符串的开头开始input
计数分隔符的下一个实例,然后从分隔符的前一个实例(或输入字符串的开头)开始计数,并将每个实例复制char
到一个新的char*
. 一旦构建了字符串,它就会被添加到char**
数组中。
还有一些有趣的位用于跳过分隔符并处理输入字符串的端点。该函数是这样使用的:
int main()
{
char* str = "mon,tue,wed,thur,fri";
char delim = ',';
char** split = string_split(str, delim);
return 1;
}
无论如何,它在大多数情况下都有效,除了char*
返回char**
数组中的第一个已损坏,并且只是被随机垃圾占据。
例如打印split
from main
yield 的元素:
split: α↨▓
split: tue
split: wed
split: thur
split: fri
奇怪的是,返回所需标记split_strings[0]
的数组的内容是char*
mon
string_split
split_strings[split_idx++] = string_element;
它将其内容从mon
垃圾。任何帮助表示赞赏,谢谢。
解决方案
您的函数至少是不正确的,因为它试图释放传递的字符串
char** string_split(char* input, char delim)
{
//...
free(charPtr);
free(input);
return split_strings;
}
就您的程序而言,它是字符串文字
char* str = "mon,tue,wed,thur,fri";
char delim = ',';
char** split = string_split(str, delim);
您不能释放字符串文字。
并且第一个参数应具有限定符const
。
您的函数中还有许多其他错误。
例如sizeof(string_element)/sizeof(char)
此语句中使用的表达式
string_element = realloc(string_element, sizeof(char) * (sizeof(string_element)/sizeof(char) + 1));
不会产生早期分配给指针指向的数组的字符数string_element
。为每个新字符重新分配数组并没有什么意义。
例如,该函数可以如下面的方式显示,如下面的演示程序所示。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char ** string_split( const char *s, char delim )
{
size_t n = 1;
char **a = calloc( n, sizeof( char * ) );
while ( *s )
{
const char *p = strchr( s, delim );
if ( p == NULL ) p = s + strlen( s );
if ( p != s )
{
char *t = malloc( p - s + 1 );
if ( t != NULL )
{
memcpy( t, s, p - s );
t[p-s] = '\0';
}
char **tmp = realloc( a, ( n + 1 ) * sizeof( char * ) );
if ( tmp == NULL )
{
free( t );
break;
}
a = tmp;
a[n-1] = t;
a[n] = NULL;
++n;
}
s = p + ( *p != '\0' );
}
return a;
}
int main(void)
{
char* str = "mon,tue,wed,thur,fri";
char delim = ',';
char **split = string_split( str, delim );
for ( char **p = split; *p != NULL; ++p )
{
puts( *p );
}
for ( char **p = split; *p != NULL; ++p ) free( *p );
free( split );
return 0;
}
程序输出为
mon
tue
wed
thur
fri
推荐阅读
- jquery - Consume XML RSS feed using jquery in a predefined template
- ag-grid - 当 stopEditingWhenGridLosesFocus 选项为 true 时,DatePicker 不起作用
- testing - 如何设置邮递员测试等于这个或那个
- c# - 构建失败,因为我杀死 vhost.exe 后无法复制 DLL
- python - 如何从立体获取深度图 - KITTI 数据集
- android - Android 房间数据库 - LiveData - 更新/插入/删除,跳过观察者(回调)
- .net - .NetCore SignalR + React - CORS 调用不起作用
- qlikview - 使用 PPtxgen 将 HTML 表格转换为 PPT
- azure - Azure devops powershell 在同一查询中给出与本地 powershell 不同的结果
- excel - 有没有办法完全限定 VBA 函数的使用?