-4

why does this cause a break in VS, I assume its because the pointer __array_buffer seems to be dealloc after update_typeArray finishes round about the third call but not always. I have no clue why. pleas help me (this is not the entire file, but the rest is mostly commented out and has no affect) this does not happen if I make update_typeArray a char * and __array_buffer = the return(return would be the pointer of __array_buffer passed in param). I would do that but I was hoping for overloading. 何でなの。please someone help me.


#include <iostream>
#include <Windows.h>
#include <thread>
#include <chrono>
#include <cmath>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <conio.h>

//winigga stuff
# define VT100_WinAPI \
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);\
DWORD dwMode = 0;\
GetConsoleMode(hOut, &dwMode);\
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;\
SetConsoleMode(hOut, dwMode);

//////////////////////////////////////////////////////////////////

/*
Increment before use if index is 0 from init, (Char)array must contain a single value, and will recive '/0'.
Size of array is calculated by overloads input type and index (with null terminater taken in to account).
*/
void update_typeArray(char * char_array, int index, char input)
{


    char * new_array = (char*)malloc(sizeof(char)*(index + 1));//+1 cause string


    for (int i = 0; i <= index; i++)
    {
        if (i < index)
        {
            new_array[i] = char_array[i];
        }
        if (i == index)
        {
            new_array[i] = '\0';//'\000' cause string
        }
    }

    free(char_array);
    new_array[index - 1] = input;
    char_array = (char*)malloc(sizeof(char)*(index + 1));//+1 cause string

    for (int i = 0; i <= index; i++)
    {
        if (i < index)
        {
            char_array[i] = new_array[i];
        }
        if (i == index)
        {
            char_array[i] = '\0';//'\000' cause string
        }
    }


    free(new_array);

}
/*
Increment before use if index is 0 from init, (Int)array must contain a single value.
Size of array is calculated by overloads input type and index.
*/
//Debug
/*
void update_typeArray(int * int_array, int index, int input)
{

    int * new_array = (int*)malloc(sizeof(int)*(index));

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

        new_array[i] = int_array[i];

    }

    free(int_array);
    new_array[index - 1] = input;
    int_array = (int*)malloc(sizeof(int)*(index));

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

        int_array[i] = new_array[i];

    }

    free(new_array);

}
*/

int main()
{

    VT100_WinAPI

    while (!(GetKeyState(0x1B) & 0x8000))
    {

        if (_kbhit()||true)
        {

            char * __array_buffer = (char*)malloc(sizeof(char)); __array_buffer[0] = '\0';
            int index = 0;
            bool chbuff_cyc = true;
            int size;

            while (chbuff_cyc)
            {
                char j[] = "reta";

                char __char_buffer = j[index];//_getch();

                if (__char_buffer == '\0')
                {
                    chbuff_cyc = false;
                    size = index;
                }
                else
                {
                    ++index;
                    update_typeArray(__array_buffer, index, __char_buffer);

                }
            }

            if (size > 0)
            {
                bool * blist = (bool*)malloc(size);
                //-----------|searchCommand (Start)|------------




                if (size == StringSize("a"))
                {
                    compare_typeArray(__array_buffer,"a",size,blist);
                    if(checkem(blist,size,and))
                    {
                        _putch('a');
                    }
                }


                //-----------|searchCommand (End)|------------
                free(blist);    
            }

            free(__array_buffer);
        }


    }

    return 0;
}

https://i.stack.imgur.com/sBZnB.jpg

Zeglo vrk
  • 3
  • 2
  • 6
    FWIW you really aren't using C++. You're basically using C in C++. – NathanOliver Sep 19 '18 at 16:25
  • 4
    Note: The name "__array_buffer" is not a valid one for you to use. Names containing double underscore (and several others; like names using "leading underscore followed by capital letter" and names ending in "_t", and more) are *reserved for the implementation* and should *not* be used in user code. – Jesper Juhl Sep 19 '18 at 16:32
  • 2
    `bool * blist = (bool*)malloc(size);` -- This seems incorrect. `malloc` does not allocate the number of `bool` values -- it allocates the number of *bytes*. Second, why not write C++ and use `std::vector`, `std::vector`, `std::string`, or some combination of those? What's all of this stuff with `malloc` about? – PaulMcKenzie Sep 19 '18 at 16:36
  • Seems like a perfect opportunity to learn how to use a debugger. – Jesper Juhl Sep 19 '18 at 16:37
  • 1
    @JesperJuhl C++ Standard makes `_t` suffix reserved for implementation? – Daniel Langr Sep 19 '18 at 16:38
  • @ NathanOliver like i said, this is only the code I'm concerned with. i have classes that are not part of the problem. @Jesper Juhl no problem has arises as a result( proof of this is that the name change does not solve the problem) – Zeglo vrk Sep 19 '18 at 16:41
  • `update_typeArray` does *nothing* to the caller's provided arguments on the caller side. I hope you understand that. Specifically, `char_array = ....` in that function means nothing to the caller, ultimately leaking memory and leaving the caller with a dangling pointer of what was originally passed in. `char_array` is passed-by-value pointer. Changing its value means nothing to the caller; only changing what it being pointed to is realized caller-side, and in this case, that change is destroying the buffer and leaving the caller hung out to dry. Any dereference of that pointer after is UB. – WhozCraig Sep 19 '18 at 16:42
  • 2
    @DanielLangr IIRC the standard doesn't. POSIX does. – HolyBlackCat Sep 19 '18 at 16:52
  • 1
    @Zeglovrk Why you don't want to use the standard containers? – HolyBlackCat Sep 19 '18 at 16:54
  • Be really careful with names like `__array_buffer`. For more on that read [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – user4581301 Sep 19 '18 at 16:55
  • 3
    @Zeglovrk The absence of evidence of a problem (in this case "no problem so far") is not proof of correctness. Undefined behavior can do anything, including appearing to work as intended for now. It's unquestionably undefined behavior to have an identifier with two consecutive underscores in c++. Even if fixing it doesn't solve this specific problem, it doesn't mean that it's not *also* a necessary fix to your code. At the very least, when diagnosing a problem, all sources of undefined behavior must be eliminated before anyone can think rationally about the code in question. – François Andrieux Sep 19 '18 at 16:58
  • 1
    What did Terry Davis say about c++ that is apparently right about? – François Andrieux Sep 19 '18 at 17:01
  • @Zeglovrk - what François said. – Jesper Juhl Sep 19 '18 at 17:08
  • @HolyBlackCat Does it mean that I should not compile/run a C++ Standard compliant code with an identifier having `_t` suffix on POSIX-based system (e.g., Linux)? What is the problem? Undefined behavior? – Daniel Langr Sep 19 '18 at 18:04
  • @DanielLangr I don't know the details. – HolyBlackCat Sep 19 '18 at 18:07
  • What will happen if you drive without a license? You probably won't get caught, but this obviously doesn't prove that driving without a license is OK. Especially in a language like C++, doing something wrong doesn't necessarily mean you will get an error. – eesiraed Sep 19 '18 at 23:05
  • @FeiXiang i understand, but once i change the name to arrayBuffer, the problem persists, so even if the __ is causing an error, it is not the current error Im concerned with. but I thankyou – Zeglo vrk Sep 20 '18 at 10:23

1 Answers1

0

One of the problem to cause undefined behavior is

In void update_typeArray(char * char_array, int index, char input) you free the memory pointed by the __array_buffer using char_array.

 update_typeArray(__array_buffer, index, __char_buffer);

 free(char_array);

and you allocate the new memory to char_array

char_array = (char*)malloc(sizeof(char)*(index + 1));//+1 cause string

but your __array_buffer will be still pointing to freed memory.

and you continue to use the __array_buffer in main after freeing

compare_typeArray(__array_buffer,"a",size,blist);

free(__array_buffer)

To understand easily consider below pictures.

 ----------------             -------
| __array_buffer |  -------> | memory| 
  ---------------             -------

after call update_typeArray(__array_buffer, index, __char_buffer);

     ----------------             -------
    | __array_buffer |  -------> | memory| 
      ---------------             -------
                                   ^
                                   |
                            ----------------
                           |    char_array |   
                             ---------------  

after free(char_array);

 ----------------             
| __array_buffer |  ------->   X 
  ---------------             
                               ^
                               |
                        ----------------
                       |   char_array   |   
                         ---------------  

After char_array = (char*)malloc(sizeof(char)*(index + 1));//+1 cause string

     ----------------             
    | __array_buffer |  ------->   X 
      ---------------             


  ----------------           -------
 |  char_array    | -----> | memory| 
   ---------------           -------

Solution:

If you want to __array_buffer to point to new memory you got use pointer to pointer as below.

void update_typeArray(char ** char_array, int index, char input)

and you call the update_type.

update_typeArray(&__array_buffer, index, __char_buffer);

your update_typeArray may look like below.

void update_typeArray(char **char_array, int index, char input)
{


    char * new_array = (char*)malloc(sizeof(char)*(index + 1));//+1 cause string


    for (int i = 0; i <= index; i++)
    {
        if (i < index)
        {
            new_array[i] = (*char_array)[i];
        }
        if (i == index)
        {
            new_array[i] = '\0';//'\000' cause string
        }
    }

    free(*char_array);
    new_array[index - 1] = input;
    *char_array = (char*)malloc(sizeof(char)*(index + 1));//+1 cause string

    for (int i = 0; i <= index; i++)
    {
        if (i < index)
        {
            (*char_array)[i] = new_array[i];
        }
        if (i == index)
        {
            (*char_array)[i] = '\0';//'\000' cause string
        }
    }


    free(new_array);

}
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44