天天看点

CSAPP学习笔记——第九章 虚拟内存(一)内存陷阱

CSAPP学习笔记——第九章 虚拟内存(一)内存陷阱

int val;
...
scanf("%d", val);
           

引用了错误的指针,scanf将val解释为一个地址,并试图将一个字写到这里

int *matvec(int **A, int *x) {
    int *y = malloc(N * sizeof(int));
    int i, j;    
    for (i = 0; i < N; i++)
        for (j = 0; j < N; j++)
            y[i] += A[i][j] * x[j];
    return y;
}
           

错误地假设堆中的数据初始化为0,应显式地设置为0,或使用calloc

int **p;
p = malloc(N * sizeof(int));
for (i = 0; i < N; i++) 
    p[i] = malloc(M * sizeof(int));
           

分配了错误的大小,不能用 sizeof(int),而应该是sizeof(int*),因为指针的长度不一定和 int 一样。

int **p;
p = malloc(N * sizeof (int *));
for (i = 0; i <= N; i++)
p[i] = malloc(M * sizeof(int));
           

超出了分配的空间,下面代码的 for 循环中,因为使用了 <=,会写入到其他位置

char s[8];
int i;
gets(s); 
           

未检查输入串的大小就写入缓冲区,造成缓冲区溢出错误,应使用fgets函数

int *search(int *p, int val) {
while (*p && *p != null)
p += sizeof(int);
return p;
}
           

指针的算术操作是以指向的对象的大小为单位进行的,例子中每次循环都将指针加4,每四个整数扫描一次

int *BinheapDelete(int **binheap, int *size) {
int *packet;
packet = binheap[0];
binheap[0] = binheap[*size - 1];
*size--;
Heapify(binheap, *size, 0);
return (packet);
}
           

*size–实际减少的是指针自己的值,而非它所指向的整数的值,应改为(*size)–

int *foo() {
    int val;    
    return &val;
}
           

引用了不存在的变量。局部变量会在函数返回的时候失效(所以对应的指针也会无效)

x = malloc(N * sizeof(int));
//  <manipulate x>
free(x);
y = malloc(M * sizeof(int));
//  <manipulate y>
free(x);
           

多次释放同一个块

x = malloc(N * sizeof(int));
//  <manipulate x>
free(x);
//  ....
y = malloc(M * sizeof(int));
for (i = 0; i < M; i++)
    y[i] = x[i]++;
           

引用了已经被释放了的块中的数据

foo() {
int *x = malloc(N * sizeof(int));
// ...
return ;
}
           

没有释放已分配的块,造成内存泄漏

继续阅读