C6385 c как исправить

I seem to get an erroneous warning message from Visual Studio 2019 (16.5 Preview but also in 16.4 and earlier) Code Analysis tool. Is this a bug, or am I really just missing something?

The warning generated (exactly) is:

warning C6385: Reading invalid data from ‘prodlist’: the readable size is ‘(size_t)*32+8′ bytes, but ’64’ bytes may be read.

Here’s the code which generates the warning (as minimal as possible)

#include <cstdint>
#include <string>
#include <iostream>

struct Product {
    std::string price_profile;
};

int getNumRows() {
    return 5;
}

Product *getProductsFromDB( int &numelements ) {
    numelements = 0;

    const int num_rows = getNumRows();
    if ( num_rows == 0 ) {
        numelements = 0;
        return nullptr;
    }

    Product *prodlist = new Product[num_rows];
    for ( int i = 0; i < num_rows; ++i ) {
        prodlist[i].price_profile = "test"; // Warning on this line
    }
    numelements = num_rows;

    return prodlist;
}

int main() {
    int num_rows;
    Product *prodlist = getProductsFromDB( num_rows );
    for ( int i = 0; i < num_rows; ++i ) {
        std::cout << prodlist[i].price_profile;
    }

    getchar();
}

If I change the price_profile to an int (and its corresponding value), or if I change num_rows to a constant (like 5) then the warning goes away.

asked Jan 8, 2020 at 16:04

ChrisMM's user avatar

ChrisMMChrisMM

8,42013 gold badges29 silver badges48 bronze badges

3

It seems in Visual Studio 2019 Microsoft is enforcing SAL analysis rules on C and C++ code by default, even though there are still plenty of false positives like your case here.

One thing you can do for now is disable the warning giving a false positive:

#pragma warning(push)
#pragma warning(disable:6385)
Product *getProductsFromDB( int &numelements ) {
 ...
}
#pragma warning(pop)

answered Jan 8, 2020 at 16:26

Govind Parmar's user avatar

Govind ParmarGovind Parmar

20.5k7 gold badges53 silver badges85 bronze badges

3

Не могу понять в чем тут проблема. Код компилируется но результат не правильный.

#include <iostream>
#include <string.h>
#include <conio.h>

using namespace std;
int main()
{
setlocale(LC_ALL, “RUSSIAN”);
char str[100];
char str2[100];
int y=0;
int kol = 0;
int s1;
int s2;

cout << “Введите текст”<<“n”;
cin.get(str, 100);
s1 = strlen(str);
str2[0] = str[0];

for(int i=0; i< s1; i++)
{

if (str[i + 1] == 0) {
y++;
str2[y] = str[i];
}
else {
if (str[i] == ‘ ‘ && str[i-1] != ‘ ‘) \ ошибка C6385
{
y++;
str2[y] = str[i – 1];
y++;
str2[y] = str[i + 1];

}
}
}
s2 = strlen(str2);
cout<<endl << s2 << endl;

for (int i = 0; i < strlen(str2); i++)
{

if (str2[i] == str2[i + 1]) {
i++;
kol++;
}
}
cout << endl << kol;

system(“pause”);

return 0;
}

I am trying to address a code analysis warning that appears in the following method:

CStringArray* CCreateReportDlg::BuildCustomAssignArray(ROW_DATA_S &rsRowData)
{
    INT_PTR         iAssign, iNumAssigns, iUsedAssign;
    CStringArray    *pAryStrCustom = nullptr;
    CUSTOM_ASSIGN_S *psAssign = nullptr;

    if (rsRowData.uNumCustomToFill > 0)
    {
        pAryStrCustom = new CStringArray[rsRowData.uNumCustomToFill];
        iNumAssigns = m_aryPtrAssign.GetSize();
        for (iAssign = 0, iUsedAssign = 0; iAssign < iNumAssigns; iAssign++)
        {
            psAssign = (CUSTOM_ASSIGN_S*)m_aryPtrAssign.GetAt(iAssign);
            if (psAssign != nullptr)
            {
                if (!psAssign->bExcluded)
                {
                    pAryStrCustom[iUsedAssign].Copy(psAssign->aryStrBrothersAll);
                    iUsedAssign++;
                }
            }
        }
    }

    return pAryStrCustom;
}

The offending line of code is:

pAryStrCustom[iUsedAssign].Copy(psAssign->aryStrBrothersAll);

I compile this code for both 32 bit and 64 bit. The warning being raised is:

Warning (C6385) Reading invalid data from pAryStrCustom: the readable size is (size_t)*40+8 bytes, but 80 bytes may be read.

I don’t know if it is relevant, but the CUSTOM_ASSIGN_S structure is defined as:

typedef struct tagCustomAssignment
{
    int             iIndex;
    CString         strDescription;
    CString         strHeading;
    BOOL            bExcluded;
    CStringArray    aryStrBrothersAll;
    CStringArray    aryStrBrothersWT;
    CStringArray    aryStrBrothersSM;
    BOOL            bIncludeWT;
    BOOL            bIncludeTMS;
    BOOL            bFixed;
    int             iFixedType;
} CUSTOM_ASSIGN_S;

My code is functional (for years) but is there a coding improvement I can make to address this issue? I have read the linked article and it is not clear to me. I have also seen this question (Reading Invalid Data c6385) along similar lines. But in my code I can’t see how that applies.

Для программы, которую я пишу, мне нужно создать массив с заданным пользователем размером, а также со случайными значениями от -15 до 15. Таким образом, я использую srand вместе с динамическим преобразованием массива. Это мой полный код ниже:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    //initialize variables
    double minValue;
    double maxValue;
    double firstQuartile;
    double thirdQuartile;
    double skewness;

    int size;
    std::cout << "Please enter the size of the data set: ";                 //get data set size from user
    std::cin >> size;
    int* dataSet = new int[size];                                                           
    cout << endl << "These are the randomly generated values: ";

    srand(static_cast<unsigned int>(time(NULL)));

    int i = size;
    for (int x = 0; x < i; x++)                                         //generate random numbers
    {
        dataSet[i] = (rand() % 31) - 15;
        cout << dataSet[i] << " ";
    }


} 

Хотя он все еще компилируется, мне нужно, чтобы это происходило без ошибок, и раздел, который я выделил ниже, вызывает две ошибки, которые я не знаю, как исправить.

int i = size;
    for (int x = 0; x < i; x++)                                         //generate random numbers
    {
        dataSet[i] = (rand() % 31) - 15;
        cout << dataSet[i] << " ";
    }

C6386 Переполнение буфера при записи в ‘dataSet’: доступный для записи размер равен ‘size * 4’ байта, но могут быть записаны ‘i’ байта.

А ТАКЖЕ

C6385 Чтение недопустимых данных из “dataSet”: читаемый размер составляет “size * 4” байта, но “i” байта могут быть прочитаны.

1 ответ

Лучший ответ

В этом цикле индексная переменная x не i.

Так что измените цикл как

int i = size;
for (int x = 0; x < i; x++)                                         //generate random numbers
{
    dataSet[x] = (rand() % 31) - 15;
    cout << dataSet[x] << " ";
}

Фактически, переменная i является избыточной и делает код подверженным ошибкам. Почему бы не написать

for (int i = 0; i < size; i++)                                         //generate random numbers
{
    dataSet[i] = (rand() % 31) - 15;
    cout << dataSet[i] << " ";
}


7

user4581301
14 Фев 2020 в 03:13

This question is most likely common and has been asked before. So, after spending a mind-numbing 30 minutes trying to find the solution to what I believe is a false negative, I’m resulting to posting my issue here.

I’m relatively new to C++ Coding and figured I’d create a simple random item generator. Unfortunately, when grasping a random index in my arrays, I am given a c6385 error. This error usually pertains to an invalid or overloaded buffer from the research I’ve found. I believe this means that the index I’m trying to access is too large thanks to rand().

I will continue looking for a solution but would like some others’ opinions of the situation. I may be overlooking a small detail or am failing to grasp a concept. All help is greatly appreciated. If I come across a solution, I will lock/remove this to overpopulate the forums.

Here is my code:
ItemGeneration.h

#pragma once
#include <random>
#include <iostream>
using namespace std;

class ItemGeneration
{
public:
    /*
        Creating the cosntant variables for the items main effects.
        For instance, if you were to roll the main attribute of "Item1",
        this code would dictate what possible attributes that could be chosen.

        In addition to the main attributes, the code for the avaliable sub-attributes is also created below.

        Also creating the const array that hold the rarity of items.
        For instance, an item that rolls a higher weighted value will have a lower rating.
        More rare or 'uncommon' the value, the higher rating the item will recieve.
        Item rarity dictates the value of the attributes assigned to ie, i.e the higher the
        rarity the higher the attributes multiplier in addition to the number of sub-attributes.
    */

    const char* Item1[4]
        = { "Attack %", "Health %", "Defense %", "Elemental Damage %" };

    const char* Item2[4]
        = { "Mana Regeneration", "Cooldown Reduction", "Healing Efficacy", "Elemental Resonance" };

    const char* Item3[4]
        = { "Raw Attack", "Raw Health", "Raw Defense", "Raw Elemental Damage" };

    const char* Item4[4]
        = { "Elemental Resonance", "Critical Chance", "Critical Multiplier", "Mana Regeneration" };

    const char* Item5[4]
        = { "Elemental Damage %", "Critial Chance", "Critical Multiplier", "Cooldown Reduction" };

    const char* SubAttributeList[10]
        = { "Raw Attack", "Raw Health", "Raw Defense", "Raw Elemental Damage", "Elemental Damage %",
            "Elemental Resonance", "Mana Regeneration", "Cooldown Reduction", "Critical Chance", "Critical Multiplier" };

    const char* RarityChart[6]
        = { "Common", "Uncommon", "Rare", "Unique", "Legendary", "Mythical" };

    const int InventoryLimit = 256;
    int InventorySize = 0;

    int ItemCreate(int x, int y) {

        int randNum = rand() % 4 + 1;

        if (InventorySize < InventoryLimit) {
            switch (x) {
            case 1:
                cout << "You have generated an Item1! Here are the resulting attributes:" << endl;
                cout << "Main Attribute: " << Item1[randNum] << endl;
                cout << "Sub-Atrributes: " << endl;
                break;

            case 2:
                cout << "You have generated an Item2! Here are the resulting attributes:" << endl;
                cout << "Main Attribute: " << Item2[randNum] << endl;
                cout << "Sub-Atrributes: " << endl;
                break;

            case 3:
                cout << "You have generated an Item3! Here are the resulting attributes:" << endl;
                cout << "Main Attribute: " << Item3[randNum] << endl;
                cout << "Sub-Atrributes: " << endl;
                break;

            case 4:
                cout << "You have generated an Item4! Here are the resulting attributes:" << endl;
                cout << "Main Attribute: " << Item4[randNum] << endl;
                cout << "Sub-Atrributes: " << endl;
                break;

            case 5:
                cout << "You have generated an Item5! Here are the resulting attributes:" << endl;
                cout << "Main Attribute: " << Item5[randNum] << endl;
                cout << "Sub-Atrributes: " << endl;
                break;

            default:
                cout << "They item you tried to generate doesn't seem to exist.nPlease enter a number between 1 and 5 to generate a random item." << endl;

            }
        }
        else {
            cout << "Sorry, your inventory is too fullnPlease clear some space before attempting to create another item." << endl;
        }
    }
};

Source.cpp

#include <iostream>
#include "ItemGeneration.h"
using namespace std;

int main() {
    int x, y;

    cout << "Welcome to the random item generator!" <<
        "nPlease enter a number between 1 and 5, " <<
        "nfollowed by a number between 1 and 10 to select its rarity, " <<
        "nto receive your own randomly generated item.n" << endl;

    cin >> x;
    cin >> y;

    ItemGeneration item;
    item.ItemCreate(x, y);
    return;
}

** Update with errors **

I should have been more concise. However, I do not believe there to be an actual buffer error, a false negative.
As for the error messages.

My main function is returning a c2561 error, but I believe that to be a side effect of the item generation, not functioning. MEaning it simply is returning the value as the function isn’t operating.
Here is my terminal readout when attempting to build the solution:

Build started...
1>------ Build started: Project: RandomItemGenerator, Configuration: Debug x64 ------
1>ItemGeneration.cpp
1>Source.cpp
1>C:UsersAlexsourcereposRandomItemGeneratorRandomItemGeneratorSource.cpp(18,2): error C2561: 'main': function must return a value
1>C:UsersAlexsourcereposRandomItemGeneratorRandomItemGeneratorSource.cpp(5): message : see declaration of 'main'
1>Generating Code...
1>Done building project "RandomItemGenerator.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

The quick solution error description:

(const char [17]) "Main Attribute: "
C6385: Reding Invalid Data from 'this->item5'.

>Solution :

int main() {
   // stuff
   return;  // <- always an error
}

Here’s your problem. You promised that main would return an int, and then you reneged on that promise with just a plain return. main is a little special in that it should return an int, so, failing all else, make it return 0.

int main() {
   // stuff
   return 0; 
}

You did it again in ItemGeneration::ItemCreate

int ItemCreate(int x, int y) 
{
   // stuff
   return;    // nope
}

But in this case, there isn’t really anything to return. Your main routine ignores the return value anyway. So you should declare it to return void instead:

void ItemCreate(int x, int y) 
{
   // stuff
   return;    // OK now (not actually needed, however)
}

Добавить комментарий