use*_*466 5 c malloc memory-management
我已经分配了一些内存,char* memoryChunk = malloc ( 80* sizeof(char) + 1);是什么阻止我写入超过81个单元的内存位置?我该怎么做才能防止这种情况发生?
void testStage2(void) {
char c_str1[20] = "hello";
char* ut_str1;
char* ut_str2;
printf("Starting stage 2 tests\n");
strcat(c_str1, " world");
printf("%s\n", c_str1); // nothing exciting, prints "hello world"
ut_str1 = utstrdup("hello ");
ut_str1 = utstrrealloc(ut_str1, 20);
utstrcat(ut_str1, c_str1);
printf("%s\n", ut_str1); // slightly more exciting, prints "hello hello world"
utstrcat(ut_str1, " world");
printf("%s\n", ut_str1); // exciting, should print "hello hello world wo", 'cause there's not enough room for the second world
}
char* utstrcat(char* s, char* suffix){
int i = strlen(s),j;
int capacity = *(s - sizeof(unsigned) - sizeof(int));
for ( j =0; suffix[j] != '\0'; j++){
if ((i+j-1) == 20)
return s;
s[i+j] = suffix[j];
}
//strcpy(s, suffix);
s[i + j] = '\0';
return s;
}// append the suffix to s
Run Code Online (Sandbox Code Playgroud)
str*_*ger 16
是什么阻止我写入超过81个单元的内存位置?
没有.但是,这样做会导致未定义的行为.这意味着任何事情都可能发生,你不应该依赖它做两次相同的事情.99.999%的时间这是一个错误.
我该怎么做才能防止这种情况发生?
在访问(读取或写入)它们之前,请务必检查指针是否在边界内.始终确保字符串\0在传递给字符串函数时结束.
您可以使用诸如valgrind之类的调试工具来帮助您找到与越界指针和数组访问相关的错误.
对于您的代码,您可以使用utstrncat哪些操作utstrcat但是采用最大大小(即缓冲区的大小).
您还可以创建数组结构/类或std::string在C++中使用.例如:
typedef struct UtString {
size_t buffer_size;
char *buffer;
} UtString;
Run Code Online (Sandbox Code Playgroud)
然后让你的功能对它进行操作.您甚至可以使用此技术进行动态重新分配(但这似乎不是您想要的).
另一种方法是使用缓冲区标记结束,类似于字符串标记的结尾.当您遇到标记时,请不要写入该位置或其前面的位置(对于字符串标记的结尾)(或者您可以重新分配缓冲区以便有更多空间).
例如,如果你有"hello world\0xxxxxx\1"一个字符串(\0字符串标记\1的结尾,是缓冲区标记的结尾,x是随机数据).附加" this is fun"内容如下所示:
hello world\0xxxxxx\1
hello world \0xxxxx\1
hello world t\0xxxx\1
hello world th\0xxx\1
hello world thi\0xx\1
hello world this\0x\1
hello world this \0\1
*STOP WRITING* (next bytes are end of string then end of buffer)
Run Code Online (Sandbox Code Playgroud)
您的代码存在问题:
if ((i+j-1) == 20)
return s;
Run Code Online (Sandbox Code Playgroud)
虽然您在超越缓冲区之前停止,但您没有标记字符串的结尾.
您可以使用过早break结束for循环而不是返回.这将导致for循环后的代码运行.这将设置字符串标记的结束并返回字符串,这是您想要的.
另外,我担心你的分配可能存在错误.你必须+ 1在字符串之前分配大小,对吗?有一个问题:unsigned通常不是1个字符; 你需要+ sizeof(unsigned)那个.我也会写utget_buffer_size,utset_buffer_size所以你可以更容易地做出改变.
| 归档时间: |
|
| 查看次数: |
1269 次 |
| 最近记录: |