我写了一个简单的C ++程序,代码如下:
// Вариант 72, задача 2.18
#include <iostream>
#define lint long long int
using std::cin;
using std::cout;
void input(lint arr[], lint arrLen) {
for (lint i = 0; i < arrLen; ++i) {
cout << "arr[" << i << "] = ";
cin >> arr[i];
}
}
void output(lint arr[], lint arrLen) {
for (lint i = 0; i < arrLen; ++i) {
cout << "newArr[" << i << "] = " << arr[i] << '\n';
}
}
bool isNumberInArray(const lint arr[], lint arrLen, lint number) {
bool isNumberPresent = false;
for (lint i = 0; i < arrLen; ++i) {
if (arr[i] == number) isNumberPresent = true;
}
return isNumberPresent;
}
void process(const lint arr[], lint arrLen, lint newArr[], lint &newArrLen, lint m, lint M) {
newArrLen = 0;
for (lint i = M; i >= m; --i) {
if (!isNumberInArray(arr, arrLen, i)) {
newArr[newArrLen] = i;
++newArrLen;
}
}
}
int main() {
lint arrLen, m, M;
cout << "Enter m\n> ";
cin >> m;
cout << "Enter M\n> ";
cin >> M;
cout << "Enter array length\n> ";
cin >> arrLen;
lint *arr = new lint[arrLen];
cout << "Enter array elements:\n";
input(arr, arrLen);
lint *newArr = new lint[arrLen], newArrLen;
process(arr, arrLen, newArr, newArrLen, m, M);
cout << "\nResults:\n";
output(newArr, newArrLen);
delete[] arr;
delete[] newArr;
return 0;
}
当我使用MSVC(x86 | Debug)编译并运行它时,它通常可以工作并产生所需的结果,但是执行后显示以下错误:
我试图使用g ++在WSL下编译程序,并使用Valgrind对其进行调试。这是我得到的:
root@seiba-laptop : /mnt/c/Users/saber-nyan/source/repos/Project1/Project1
[130] # g++ ./main.cpp -O0 -ggdb -o ./main
root@seiba-laptop : /mnt/c/Users/saber-nyan/source/repos/Project1/Project1
[0] # valgrind ./main
==316== Memcheck, a memory error detector
==316== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==316== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==316== Command: ./main
==316==
==316== error calling PR_SET_PTRACER, vgdb might block
Enter m
> 1
Enter M
> 5
Enter array length
> 2
Enter array elements:
arr[0] = 4
arr[1] = 2
==316== Invalid write of size 8
==316== at 0x1093A4: process(long long const*, long long, long long*, long long&, long long, long long) (main.cpp:34)
==316== by 0x1094E4: main (main.cpp:57)
==316== Address 0x4d60560 is 0 bytes after a block of size 16 alloc'd
==316== at 0x483850F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==316== by 0x1094BA: main (main.cpp:55)
==316==
Results:
newArr[0] = 5
newArr[1] = 3
==316== Invalid read of size 8
==316== at 0x1092B7: output(long long*, long long) (main.cpp:18)
==316== by 0x10950A: main (main.cpp:60)
==316== Address 0x4d60560 is 0 bytes after a block of size 16 alloc'd
==316== at 0x483850F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==316== by 0x1094BA: main (main.cpp:55)
==316==
newArr[2] = 1
==316==
==316== HEAP SUMMARY:
==316== in use at exit: 0 bytes in 0 blocks
==316== total heap usage: 5 allocs, 5 frees, 74,784 bytes allocated
==316==
==316== All heap blocks were freed -- no leaks are possible
==316==
==316== For counts of detected and suppressed errors, rerun with: -v
==316== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
有什么问题以及如何解决?
答案 0 :(得分:5)
我了解的是您尝试构建一个新数组,其中包含原始数组中不存在的值。在您的情况下,您首先构建[4,2]并尝试构建[5,3,1],因为[4,2]中不存在的M = 5,m = 1之间的值是[5,3,1]。
您的问题是,您首先将newArr
构建为长度为2(与arr
相同的长度)的数组。但是您不能将3个值放入大小为2的数组中。
==316== Invalid write of size 8
==316== at 0x1093A4: process(long long const*, long long, long long*, long long&, long long, long long) (main.cpp:34)
==316== by 0x1094E4: main (main.cpp:57)
==316== Address 0x4d60560 is 0 bytes after a block of size 16 alloc'd
==316== at 0x483850F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==316== by 0x1094BA: main (main.cpp:55)
Invalid write of size 8
表示您试图在某个错误的地址处写一个long long int
。
Address 0x4d60560 is 0 bytes after a block of size 16 alloc'd
表示valgrind检测到您的错误写入位于大小为16的内存块的末尾,恰好是两个long long int
s数组的大小。
答案 1 :(得分:0)
问题在于您的newArr不一定有足够的空间来容纳所有长整数。这取决于M和m的值,M和m的值决定了process(...)中的for循环要进行多少次迭代以及将值存储在arr中。
要修复此问题,请在此行中:
分配(M-m +1)而不是新皮棉的数量。
您还应确保M> m