c++ 为什么在写入'ptr'时收到警告'C6386'缓冲区溢出?

eqoofvh9  于 2022-12-24  发布在  其他
关注(0)|答案(3)|浏览(358)

'变量' size '在这个例子中是10。如果我硬编码10来代替' int(size)',溢出警告就会消失。为什么会发生这种情况?我想为指针分配80个字节,每个分配的值都是给定时间跨度的一个时间步。
谢谢大家!

int main() {
    const double h = 0.1;
    const double tspan[2] = { 0.0, 1.0 };
    const double size =round(tspan[1] / h);
    double *ptr = (double*)malloc(int(size) * sizeof(double));

    if (!ptr) {
        cout << "Memory Allocation Failed";
        exit(1);
    }

    double j = 0;
    for (int i = 0; i < size; i++) {
        ptr[i] = j;
            
        //cout << j << '\n';
        j++;
    }

    cout << '\n';
    for (int i = 0; i < size; i++) {
        cout << *(ptr + i) << endl;
        //cout << i << '\n';
    }
    
    
    free(ptr);
    return 0;
}

我已经试过解引用指针并确保它不为NULL。我还打印了结果。结果是一个计数为0 - 9的指针。

xa9qqrwz

xa9qqrwz1#

double size可以是10.1,如果i是10,则条件i < 10.1不终止循环,分配的缓冲区大小是int(10.1),即10,ptr[10]导致缓冲区溢出。

xxhby3vn

xxhby3vn2#

作为对273K答案的补充,你可以通过将size作为int变量来解决这个问题。如果我们一直使用nint作为size,那么在循环测试中比较时就不可能被浮点问题所困扰。
让我们将除法的结果取底并强制转换为int

int main() {
    const double h = 0.1;
    const double tspan[2] = { 0.0, 1.0 };
    const int size = static_cast<int>(std::floor(tspan[1] / h));
    double *ptr = (double*)malloc(size * sizeof(double));

    if (!ptr) {
        cout << "Memory Allocation Failed";
        exit(1);
    }

    double j = 0;
    for (int i = 0; i < size; i++) {
        ptr[i] = j;
            
        //cout << j << '\n';
        j++;
    }

    cout << '\n';
    for (int i = 0; i < size; i++) {
        cout << *(ptr + i) << endl;
        //cout << i << '\n';
    }
    
    free(ptr);
    return 0;
}

更好的是,让我们使用new和delete来代替malloc和free。

int main() {
    const double h = 0.1;
    const double tspan[2] = { 0.0, 1.0 };
    const int size = static_cast<int>(std::floor(tspan[1] / h));
    double *ptr = new double[size];

    if (!ptr) {
        std::cout << "Memory Allocation Failed";
        exit(1);
    }

    double j = 0;
    for (int i = 0; i < size; i++) {
        ptr[i] = j;
            
        //std::cout << j << '\n';
        j++;
    }

    std::cout << '\n';
    for (int i = 0; i < size; i++) {
        std::cout << *(ptr + i) << std::endl;
        //cout << i << '\n';
    }
    
    delete[] ptr;
    return 0;
}

更好的是,使用std::vector,我们不需要担心自己管理内存,我们可以使用更聪明的for循环,让向量负责边界检查。

int main() {
    const double h = 0.1;
    const double tspan[2] = { 0.0, 1.0 };
    const int size = static_cast<int>(std::floor(tspan[1] / h));
    std::vector<double> vec(size);

    double j = 0;
    for (auto &x : vec) {
        x = j;
            
        //std::cout << j << '\n';
        j++;
    }

    std::cout << '\n';
    for (auto x : vec) {
        std::cout << x << std::endl;
        //std::cout << i << '\n';
    }

    return 0;
}
ffdz8vbo

ffdz8vbo3#

round()四舍五入到最接近的整数。如果需要,您应该使用ceil()将**向上四舍五入。

相关问题