It is just a warning but it is giving good advice. What if the file contains more than num
items? The warning is telling you that should make sure you don’t write past the end of the array. Specifically:
This warning indicates that the writable extent of the specified buffer might be smaller than the index used to write to it. This can cause buffer overrun. [msdn]
This code does not produce the warning (VS2019):
int x, y;
while (i < num && (file >> x >> y)) {
points[i].x = x;
points[i].y = y;
i++;
}
There is still more error checking to add. What if file >> num;
fails? What if num
is negative ? What if points = new point[num];
fails (returns nullptr
)?
Updated with full error checking:
struct point {
int x, y;
};
void main()
{
ifstream file("C:\Users\Den\Desktop\file.txt");
if (!file) {
cerr << "No file foundn";
exit(-1);
}
int num;
if (!(file >> num) || num <= 0) {
cerr << "invalid numn";
exit(-1);
}
point *points = new point[num];
if (!points) {
cerr << "new failedn";
exit(-1);
}
int num_items = 0;
while (num_items < num && file >> points[num_items].x >> points[num_items].y) {
num_items++;
}
// Do some work here
delete [] points;
}
In the future, consider using std::vector
over raw array.
savvakhrenkov 0 / 0 / 0 Регистрация: 19.02.2022 Сообщений: 2 |
||||
1 |
||||
19.02.2022, 21:30. Показов 1559. Ответов 5 Метки нет (Все метки)
Необходимо задать динамический массив структур из номера строки и указателя на строку и по запросу пользователя инвертировать одну из строк. При компиляции на моменте с инвертированием строки номер «a» компилятор VS Studio 2019 выдает предупреждения C6385 и C6386 (строки 51 и 52 соответственно). Никак не могу понять, отчего так. Код прилагаю.
0 |
687 / 393 / 201 Регистрация: 19.12.2016 Сообщений: 1,599 |
|
19.02.2022, 21:48 |
2 |
А у вас
0 |
фрилансер 4792 / 4392 / 935 Регистрация: 11.10.2019 Сообщений: 11,568 |
|
19.02.2022, 21:56 |
3 |
выдает предупреждения текст предупреждений то какой ? Добавлено через 2 минуты
0 |
0 / 0 / 0 Регистрация: 19.02.2022 Сообщений: 2 |
|
19.02.2022, 22:06 [ТС] |
4 |
C6385 Чтение недопустимых данных из «Array[invert].str»: доступный для чтения объем равен «size*1» байт, однако считать можно только «2» байт. Добавлено через 4 минуты
это учебное задание на динамические массивы или боевой код Учебное задание Добавлено через 2 минуты
А у вас #include <cstring> подключен? Подключена библиотека . На мой VS плюется и не находит.
0 |
687 / 393 / 201 Регистрация: 19.12.2016 Сообщений: 1,599 |
|
19.02.2022, 22:10 |
5 |
не находит. Как тогда strlen может работать?
0 |
24 / 57 / 31 Регистрация: 06.08.2020 Сообщений: 210 |
|
19.02.2022, 22:21 |
6 |
В VS нормально работает с #include<string> хотя да, по идее strlen это сишный прикол. А предупреждения мне думается это студию смущает некоторая непонятность переменной invert. Но на работу это не влияет.
0 |
In my code, I am using an array xyz
of 10 objects. When I am trying to access an element of the array using an unsigned int index like this: xyz[level]
, I get ‘Buffer overrun’ warning. Logically, I am pretty sure that level won’t exceed 10. How to avoid this warning?
Paul R
208k36 gold badges386 silver badges556 bronze badges
asked Jun 11, 2010 at 10:43
2
I’m probably teaching my grandmother to suck eggs here, but do remember that «level won’t exceed 10» is wrong for an array of size 10:
char a[10];
a[10] = ''; // Bug, and "Buffer Overrun" warning.
answered Jun 11, 2010 at 10:52
RichieHindleRichieHindle
270k47 gold badges356 silver badges398 bronze badges
3
Are you really sure? I never got this warning until now. So, double check.
Anyway, you can use the
#pragma warning( disable: 6386 )
preprocessor directive. I usually push and pop this to the «pragma stack»
#pragma warning( push )
#pragma warning( disable : 6386 )
// Some code
#pragma warning( pop )
as advised here.
answered Jun 11, 2010 at 10:53
mkluwemkluwe
3,7732 gold badges27 silver badges45 bronze badges
1
Permalink
Cannot retrieve contributors at this time
description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid | |||
---|---|---|---|---|---|---|---|---|
Learn more about: Warning C6386 |
Warning C6386 |
11/04/2016 |
|
C6386 |
84e69fe8-8f03-4bb3-b194-e5551882e214 |
Warning C6386
Buffer overrun: accessing ‘buffer name‘, the writable size is ‘size1‘ bytes, but ‘size2‘ bytes may be written: Lines: x, y
Remarks
This warning indicates that the writable extent of the specified buffer might be smaller than the index used to write to it. This defect can cause buffer overrun.
Code analysis name: WRITE_OVERRUN
Example
The following code generates both this warning and C6201:
#define MAX 25 void f ( ) { char ar[MAX]; // code ... ar[MAX] = ''; }
To correct both warnings, use the following code:
#define MAX 25 void f ( ) { char a[MAX]; // code ... a[MAX - 1] = ''; }
See also
C6201
есть вот такой код, который для каждого объекта из folderList создает свой поток
DWORD hThreadArraySize = sizeof(HANDLE);
hThreadArraySize*=folderList.size();
hThreadArray = (HANDLE*)VirtualAlloc(NULL, hThreadArraySize, MEM_COMMIT, PAGE_READWRITE);
for (std::list<FOLDERDESCRIPTOR>::iterator it = folderList.begin(); it != folderList.end(); it++, i++)
{
hThreadArray[i] = (*it).hThread = CreateThread();
}
И на него выдается предупреждение анализатора кода
Warning C6386 Buffer overrun while writing to ‘hThreadArray’: the writable size is ‘hThreadArraySize’ bytes, but ‘8’ bytes might be written.
Почему оно возникает и как исправить? я все размеры проверил, все хорошо. Но что то же ему не нравистя
- Forum
- General C++ Programming
- c++ buffer overrun warning error C6386
c++ buffer overrun warning error C6386
Hi all
The program below executes OK but getting one warning C6386 as shown below:
«warning C6386: Buffer overrun while writing to ‘df.m_Dats’: the writable size is ‘(unsigned __int64 size_t)*32′ bytes, but ’64’ bytes might be written.»
Any idea how to fix this? Is this vs2019 compiler bug and a known issue?
|
|
Last edited on
I doubt it’s a vs2019 compiler bug, especially without more evidence. <Edit: As seeplus mentioned, sometimes intellisense can show errors, and it may be strict or give false positives, but it still might point to a possible improvement.>
You need to show a minimal reproducible example.
The following uses your code verbatim, but produces no warnings at warning level 4:
|
|
If I had to guess? It’s that cast to (uint32_t) from size_t (64-bit). Or, it’s complaining about how dataidx is only 32-bit.
Last edited on
Is this a build warning or an intellisense warning?
I was Running Code Analysis for C/C++ from VS2019 and ended up with this warning message, though my program executes OK. i am trying to figure out what went wrong in my code. Have updated above code and warning message occured at line 27: df.m_Dats[ dataidx++ ] = frame;
Last edited on
To make any kind of intelligent guess at what’ might be the problem, you should include the following in your code snippet:
— Declaration of Dataframe.
— Declaration of Key
— Declaration of uidToDraw
— Declaration of Data
I have added those declarations in the code above. Please check it.
Still a rubbish attempt at http://sscce.org/
|
|
You don’t reset dataidx back to zero for your second pass through the f loop, so your second round of the ti loop uses a very non-zero dataidx value and keeps on incrementing from there on.
But how would we know, you’ve never shown how dataidx is declared or initialised.
Also, to stop your code looking like it’s been dragged through a hedge, only use spaces for indentation (most modern editors deal with indentation very well).
A heady mix of spaces and tabs is a mess when posted.
> The program below executes OK
Sure it does.
But the very nature of «undefined behaviour» necessarily includes «doing what I expected».
> Is this vs2019 compiler bug and a known issue?
It’s remarkable the number of wet behind the ears noobs who show up wondering whether it’s a compiler bug (a compiler used by many 1000’s of experienced professionals on a daily basis) is a possible alternative to their own code being wrong.
Topic archived. No new replies allowed.
Я пытаюсь реализовать сортировку слиянием в C, когда натолкнулся на что-то интересное, поднятое [Analyze -> Run Code Analysis] в Visual Studio 2015.
Код выглядит следующим образом:
void MergeSort_r(int A[], int n)
{
// A = {1, 3, 2}
// n = 3
int rightCount;
int* R;
if ( n < 2 ) return;
// version 1: rightCount = 2
rightCount = n - (n/2);
// version 2: rightCount = 2
rightCount = n - 1;
R = ( int* ) malloc( rightCount * sizeof( int ) );
if ( R ) {
for ( int i = 0; i < rightCount; i++ ) {
R[i] = A[i];
}
free( R );
}
}
Хотя обе версии rightCount по существу оцениваются как 2, в первой версии я получаю предупреждение:
«Переполнение буфера при записи в ‘R’: размер записи равен ‘(unsigned int) rightCount * sizeof (int)’ байтов, но может быть записано 8 байтов.»
Есть идеи, почему это так? Будем рады услышать ваши ответы.
2
Решение
Набор инструментов для анализа кода в Visual C ++ не всегда предлагает лучшие предупреждения. Он пытается дать вам лучший набор предупреждений, чтобы исправить некоторые потенциальные проблемы / ошибки, которые могут появиться во время выполнения. У вас есть несколько вариантов:
- Отключите данное предупреждение вокруг кода, используя
#pragma
директивы. - Используйте конструкции C ++:
new
,make_unique
и т.п. - (Не рекомендуется) это полностью игнорировать предупреждение и двигаться дальше.
В идеале вы всегда должны использовать новые примитивы smart pointers, такие как unique_ptr
, shared_ptr
и т.д. Они не только выделяют память для вас, но и освобождают от любого исключения, выброшенного в стек вызовов. Вам не нужно вводить *
полностью!
auto buffer = make_unique<int[]>(10); // 10 integers
3
Другие решения
Ваш код в порядке, и инструменты (особенно анализаторы) имеют свои недостатки — иногда они генерируют ложные срабатывания. Это один из них. Кстати, я проверил ваш код на MSVS2015, и он не дает мне никаких предупреждений.
3
Solution 1
Static code analysis is hard, tracing possible values of an expression like 3 + 2 * nNumItems
is hard, and tracing actual possible values is often near to impossible. This is why it is a warning, not error. So far for the obvious.
Now, looking at how you describe that this warning behaves, I would bet on a «bug», or rather, I should say it with less stress, deficiency, in the static analyzer.
I can see some imaginary possible causes behind this warning on original nWords[1] = 2
and global nNumItems
. They are really weird and I don’t think a reasonable analyst would add such rules to the analyzer. Also, I were right, then you should have these warnings on nWords[0] = 1
as well.
The fact that you don’t see them on that proves my ideas wrong, so I stop here.
Instead, I would like to focus on that static code analysis is hard. It does not matter how well-written the analyzer and its rules are. For some cases, it will make errors, and for other cases it will simply fail and won’t be even able to guess, and for other cases it will timeout and just let go. Until we have some breakthrough in AI or breakthrough in solving NP-hard problems, you will probably have to get used to the fact, that when you are using static code analyzers, then you have to write code in a way that they can comprehend, not count on that they can comprehend everything you can write.
Last thought, when I see this error:
file.cpp(18): warning C6386: Buffer overrun while writing to ‘nWords’: the writable size is ‘nTotal*4’ bytes, but ‘8’ bytes might be written.
the first thing that I notice is nTotal*4
and 8
. If you were using a hardcoded values, you would probably get an error like
file.cpp(18): warning C6386: Buffer overrun while writing to ‘nWords’: the writable size is ‘1024’ bytes, but ‘8192’ bytes might be written.
The fact that you see nTotal*4
seems to imply that the static code analyzer actually failed to guess the value under nTotal
and it left it as symbolic name, which formed an expression incomparable to 8
. Therefore, the analyzer did theonly thing it could — it reported a problem, and described it as well as it could. Still, it’s just my guess.
// EDIT — note for Dan’s answer about guessing: nNumItems <- SIZE_MAX
I actually think that he’s may be quite about the SIZE_MAX. I played a bit with some SAT solvers from Microsoft, and one thing they did well was solving set of constraints in integer domain. Actually unsigned int x = SIZE_MAX; std::cout << ( (3+2*x)*sizeof(int) );
prints 4 (of course), and that is the only value of x
for which the expression is less than 8.
I’m pretty sure that the constraint solver from microsoft I played with can detect this case when checking satisfiability of ((3+2*x)*4) < 8
in integer ring domain — hence the warning could be issued. However, I would expect the warning to include the result and print something like:
nTotal*4 < 8 when {nTotal=1,nNumItems=4294967295}`
since the analyzer had would have this information already. But then, that’s.. probably expecting too much from it. Developers behind it probably wouldn’t have thought of formatting such detailed warning message, or considered current format of the message to be more user-friendly.
Solution 2
Since nNumItems
is global, it would appear that code analyzer thinks that nNumItems
might be set to SIZE_MAX elsewhere before your code executes. You can see this with a sample like:
size_t nNumItems = 0;
void foo()
{
nNumItems = SIZE_MAX;
}
void bar()
{
const size_t nTotal = 3 + 2 * nNumItems;
auto nWords = new int[nTotal];
nWords[0] = 1;
nWords[1] = 2;
}
int main()
{
foo();
bar();
return 0;
}
Perhaps the best fix is to side-step the entire problem by using std::vector<int>
.
Comments
-
I’ve read a lot about the Visual Studio Code Analysis warning C8386, but can’t figure out this particular issue with my code. I’ve reduced it to the following small program:
unsigned int nNumItems = 0; int main() { int *nWords=nullptr; unsigned int nTotal; nTotal = 3 + 2 * nNumItems; nWords = new int[nTotal]; nWords[0] = 1; nWords[1] = 2; // this is line 18, warning C6386 delete[] nWords; return 0; }
Analyze->Run Code Analysis->On Solution will give the following warning:
file.cpp(18): warning C6386: Buffer overrun while writing to ‘nWords’: the writable size is ‘nTotal*4’ bytes, but ‘8’ bytes might be written.
Is this legit? Now, if I move my global variable and make it local, the warning disappears!
int main() { unsigned int nNumItems = 0; ... }
But I can’t do this as in the full code, this is a member variable.
Likewise, if I move the definition of nTotal into the ‘new int‘, I can also remove the warning:
nWords = new int[3 + 2 * nNumItems];
But I can’t do this as nWords is referred to in other places in the full code.
Is this just an issue with the Visual Studio static code analyzer, or is it a legitimate issue with this code?
-
Static analysis is at least as hard as the halting problem. That’s why static-analyzers don’t always do a good job.
-
presumably other parts of the code want to change
nNumItems
-
Warnings do not go away by restarting the IDE. Of course, you won’t see them directly because the message window will be empty on start, but the warning will reappear every time you compile the code. Besides, the other answers already proved it’s not a false positive. There are actual use cases where it could lead to a buffer overrun.