C程序是Damereau-Levenshtein算法,它使用矩阵比较两个字符串。在的第四行main()
,我要malloc()
为矩阵(2d数组)存储。在测试中,我分配了(0),它仍然运行良好。看来无论我输入了什么malloc()
,该程序仍然有效。为什么是这样?
我在Visual Studio开发人员命令提示符中使用“ cl”命令编译了代码,但未收到任何错误。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main(){
char y[] = "felkjfdsalkjfdsalkjfdsa;lkj";
char x[] = "lknewvds;lklkjgdsalk";
int xl = strlen(x);
int yl = strlen(y);
int** t = malloc(0);
int *data = t + yl + 1; //to fill the new arrays with pointers to arrays
for(int i=0;i<yl+1;i++){
t[i] = data + i * (xl+1); //fills array with pointer
}
for(int i=0;i<yl+1;i++){
for(int j=0;j<xl+1;j++){
t[i][j] = 0; //nulls the whole array
}
}
printf("%s", "\nDistance: ");
printf("%i", distance(y, x, t, xl, yl));
for(int i=0; i<yl+1;i++){
for(int j=0;j<xl+1;j++){
if(j==0){
printf("\n");
printf("%s", "| ");
}
printf("%i", t[i][j]);
printf("%s", " | ");
}
}
}
int distance(char* y, char* x, int** t, int xl, int yl){
int isSub;
for(int i=1; i<yl+1;i++){
t[i][0] = i;
}
for(int j=1; j<xl+1;j++){
t[0][j] = j;
}
for(int i=1; i<yl+1;i++){
for(int j=1; j<xl+1;j++){
if(*(y+(i-1)) == *(x+(j-1))){
isSub = 0;
}
else{
isSub = 1;
}
t[i][j] = minimum(t[i-1][j]+1, t[i][j-1]+1, t[i-1][j-1]+isSub); //kooks left, above, and diagonal topleft for minimum
if((*(y+(i-1)) == *(x+(i-2))) && (*(y+(i-2)) == *(x+(i-1)))){ //looks at neighbor characters, if equal
t[i][j] = minimum(t[i][j], t[i-2][j-2]+1, 9999999); //since minimum needs 3 args, i include a large number
}
}
}
return t[yl][xl];
}
int minimum(int a, int b, int c){
if(a < b){
if(a < c){
return a;
}
if(c < a){
return c;
}
return a;
}
if(b < a){
if(b < c){
return b;
}
if(c < b){
return c;
}
return b;
}
if(a==b){
if(a < c){
return a;
}
if(c < a){
return c;
}
}
}
malloc(0)
部分:在的手册页中malloc()
,
该
malloc()
函数分配大小字节,并返回指向分配的内存的指针。内存未初始化。如果size为0,则malloc()
返回NULL
,或者返回一个唯一的指针值,以后可以将其成功传递给free()
。
因此,返回的指针是NULL
或只能固定到的指针free()
,您不能期望取消对该指针的引用并将某些内容存储到内存位置。
在上述两种情况下,您都试图使用无效的指针,它会调用未定义的行为。
一旦程序到达UB,无论如何该输出就无法证明是正确的。
UB的主要成果之一就是“工作得很好”(正如“错误地”预期的那样)。
就是说,追随类比
“您可以分配零大小的分配,只是不能取消引用它”
一些内存调试器应用程序暗示的使用malloc(0)
可能是不安全的,并将包括对的调用在内的语句更改为红色区域malloc(0)
。
malloc(<any_size>)
部分:通常,再次访问绑定内存是UB。如果碰巧在分配的内存区域之外进行访问,则无论如何都会调用UB,并且推测的结果无法定义。
FWIW,C本身并不强加/执行任何边界检查。因此,您不受“限制”(读作“编译器错误”)的访问超出范围的内存,但这样做会调用UB。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句