0

I searched other questions about this issue and found a load of them but I do not feel like they fit my peculiar case. I need to retrieve a list of smartcard readers from PCSClite on Debian 9 GNU/Linux, using g++ (Debian 6.3.0-18) 6.3.0. Such list is in the form of a char* array returned by a PCSC API method. Each reader name is separated from the neighboring ones by a \000 null character. Once the char array has been correctly formed (I checked with gdb), I use the following code snippet to build the list of names:

LONG iterationTotal = 0;    // total number of processed characters
std::list<char*> ReaderList; // the final list of names
while (iterationTotal < dwReaders) {  // dwReaders is returned by PCSC
                                      // it is the total length of the
                                      // char* array 
    LONG i = 0;
    while (mszReaders[i] != NULL) { //mszReaders is the char* array
        i++;
        iterationTotal++;  
    }
    iterationTotal++;   // counts the NULL characters that separe names
    char * tempReader = new char(i + 1);    // allocate just enough 
                                            //memory for the current name
    strcpy(tempReader, mszReaders); // copy name contents
    std::cout << tempReader << std::endl; // this prints CORRECTLY the 
                                          // names of the readers

    mszReaders += i;    // "erases" the previous name
    mszReaders += 1;    // takes into account the NULL char

    ReaderList.push_back(tempReader);  // add element to list
    //DELETE!
    //delete[] tempReader;   // I cannot uncomment this! Don't know why

    i = 0;
}

for (std::list<char*>::iterator it = ReaderList.begin(); it != ReaderList.end(); it++) {
    std::cout << *it << std::endl;     // shows the elements present in
                                       // the list
}

The output at execution is:

bjorn@debianHDD:~/Documents/Arjo/products/omnilector_C#_original/trials$ ./listReaders
Established context.
Successfully obtained reader list
Identiv Identiv uTrust 4701 F Dual Interface Reader [uTrust 4701 F CL Reader] (55041546201112) 00 00
Identiv Identiv uTrust 4701 F Dual Interface Reader [uTrust 4701 F Contact Reader] (55041546201112) 01 00

Identiv Identiv uTrust 4!
Identiv Identiv uTrust 4!

208
*** Error in `./listReaders': free(): invalid next size (fast): 0x0000561a18e3d370 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bcb)[0x7ffbe2f55bcb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76f96)[0x7ffbe2f5bf96]
/lib/x86_64-linux-gnu/libc.so.6(+0x777de)[0x7ffbe2f5c7de]
./listReaders(+0x1904)[0x561a172f0904]
./listReaders(+0x17bc)[0x561a172f07bc]
./listReaders(+0x1632)[0x561a172f0632]
./listReaders(+0x14b3)[0x561a172f04b3]
./listReaders(+0x12f8)[0x561a172f02f8]
./listReaders(+0x12a4)[0x561a172f02a4]
./listReaders(+0x10dc)[0x561a172f00dc]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7ffbe2f052b1]
./listReaders(+0xd3a)[0x561a172efd3a]
======= Memory map: ========
561a172ef000-561a172f2000 r-xp 00000000 08:12 7350775                    /home/bjorn/Documents/Arjo/products/omnilector_C#_original/trials/listReaders
561a174f1000-561a174f2000 r--p 00002000 08:12 7350775                    /home/bjorn/Documents/Arjo/products/omnilector_C#_original/trials/listReaders
561a174f2000-561a174f3000 rw-p 00003000 08:12 7350775                    /home/bjorn/Documents/Arjo/products/omnilector_C#_original/trials/listReaders
561a18e2b000-561a18e5d000 rw-p 00000000 00:00 0                          [heap]
7ffbdc000000-7ffbdc021000 rw-p 00000000 00:00 0 
7ffbdc021000-7ffbe0000000 ---p 00000000 00:00 0 
7ffbe28bc000-7ffbe28d4000 r-xp 00000000 08:12 10488851                   /lib/x86_64-linux-gnu/libpthread-2.24.so
7ffbe28d4000-7ffbe2ad3000 ---p 00018000 08:12 10488851                   /lib/x86_64-linux-gnu/libpthread-2.24.so
7ffbe2ad3000-7ffbe2ad4000 r--p 00017000 08:12 10488851                   /lib/x86_64-linux-gnu/libpthread-2.24.so
7ffbe2ad4000-7ffbe2ad5000 rw-p 00018000 08:12 10488851                   /lib/x86_64-linux-gnu/libpthread-2.24.so
7ffbe2ad5000-7ffbe2ad9000 rw-p 00000000 00:00 0 
7ffbe2ad9000-7ffbe2ae0000 r-xp 00000000 08:12 10488867                   /lib/x86_64-linux-gnu/librt-2.24.so
7ffbe2ae0000-7ffbe2cdf000 ---p 00007000 08:12 10488867                   /lib/x86_64-linux-gnu/librt-2.24.so
7ffbe2cdf000-7ffbe2ce0000 r--p 00006000 08:12 10488867                   /lib/x86_64-linux-gnu/librt-2.24.so
7ffbe2ce0000-7ffbe2ce1000 rw-p 00007000 08:12 10488867                   /lib/x86_64-linux-gnu/librt-2.24.so
7ffbe2ce1000-7ffbe2ce4000 r-xp 00000000 08:12 10486046                   /lib/x86_64-linux-gnu/libdl-2.24.so
7ffbe2ce4000-7ffbe2ee3000 ---p 00003000 08:12 10486046                   /lib/x86_64-linux-gnu/libdl-2.24.so
7ffbe2ee3000-7ffbe2ee4000 r--p 00002000 08:12 10486046                   /lib/x86_64-linux-gnu/libdl-2.24.so
7ffbe2ee4000-7ffbe2ee5000 rw-p 00003000 08:12 10486046                   /lib/x86_64-linux-gnu/libdl-2.24.so
7ffbe2ee5000-7ffbe307a000 r-xp 00000000 08:12 10486022                   /lib/x86_64-linux-gnu/libc-2.24.so
7ffbe307a000-7ffbe327a000 ---p 00195000 08:12 10486022                   /lib/x86_64-linux-gnu/libc-2.24.so
7ffbe327a000-7ffbe327e000 r--p 00195000 08:12 10486022                   /lib/x86_64-linux-gnu/libc-2.24.so
7ffbe327e000-7ffbe3280000 rw-p 00199000 08:12 10486022                   /lib/x86_64-linux-gnu/libc-2.24.so
7ffbe3280000-7ffbe3284000 rw-p 00000000 00:00 0 
7ffbe3284000-7ffbe329a000 r-xp 00000000 08:12 10485968                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffbe329a000-7ffbe3499000 ---p 00016000 08:12 10485968                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffbe3499000-7ffbe349a000 r--p 00015000 08:12 10485968                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffbe349a000-7ffbe349b000 rw-p 00016000 08:12 10485968                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffbe349b000-7ffbe359e000 r-xp 00000000 08:12 10486050                   /lib/x86_64-linux-gnu/libm-2.24.so
7ffbe359e000-7ffbe379d000 ---p 00103000 08:12 10486050                   /lib/x86_64-linux-gnu/libm-2.24.so
7ffbe379d000-7ffbe379e000 r--p 00102000 08:12 10486050                   /lib/x86_64-linux-gnu/libm-2.24.so
7ffbe379e000-7ffbe379f000 rw-p 00103000 08:12 10486050                   /lib/x86_64-linux-gnu/libm-2.24.so
7ffbe379f000-7ffbe3911000 r-xp 00000000 08:12 12584202                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7ffbe3911000-7ffbe3b11000 ---p 00172000 08:12 12584202                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7ffbe3b11000-7ffbe3b1b000 r--p 00172000 08:12 12584202                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7ffbe3b1b000-7ffbe3b1d000 rw-p 0017c000 08:12 12584202                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7ffbe3b1d000-7ffbe3b21000 rw-p 00000000 00:00 0 
7ffbe3b21000-7ffbe3b2b000 r-xp 00000000 08:12 12593178                   /usr/lib/x86_64-linux-gnu/libpcsclite.so.1.0.0
7ffbe3b2b000-7ffbe3d2a000 ---p 0000a000 08:12 12593178                   /usr/lib/x86_64-linux-gnu/libpcsclite.so.1.0.0
7ffbe3d2a000-7ffbe3d2b000 r--p 00009000 08:12 12593178                   /usr/lib/x86_64-linux-gnu/libpcsclite.so.1.0.0
7ffbe3d2b000-7ffbe3d2c000 rw-p 0000a000 08:12 12593178                   /usr/lib/x86_64-linux-gnu/libpcsclite.so.1.0.0
7ffbe3d2c000-7ffbe3d4f000 r-xp 00000000 08:12 10485946                   /lib/x86_64-linux-gnu/ld-2.24.so
7ffbe3f16000-7ffbe3f1c000 rw-p 00000000 00:00 0 
7ffbe3f4b000-7ffbe3f4f000 rw-p 00000000 00:00 0 
7ffbe3f4f000-7ffbe3f50000 r--p 00023000 08:12 10485946                   /lib/x86_64-linux-gnu/ld-2.24.so
7ffbe3f50000-7ffbe3f51000 rw-p 00024000 08:12 10485946                   /lib/x86_64-linux-gnu/ld-2.24.so
7ffbe3f51000-7ffbe3f52000 rw-p 00000000 00:00 0 
7ffd8cc53000-7ffd8cc74000 rw-p 00000000 00:00 0                          [stack]
7ffd8cc81000-7ffd8cc83000 r--p 00000000 00:00 0                          [vvar]
7ffd8cc83000-7ffd8cc85000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

As you can see, the problem arises when returning, so this is something happening when releasing the memory occupied by the list. Supporting this idea: if I uncomment the DELETE line in the while loop (I really should delete that variable to avoid the memory leak) the program stops with this free(): invalid next size (fast): error. Moreover, I can't see why the list only appears to contain a small part of the names, the push_back method should add the whole content of tempReader to the list. I tried to run the program through Valgrind but I honestly can't see the problem (I can post its output if it can help) What is the cause of the error? How can I solve this situation?

bjorn
  • 33
  • 7
  • 6
    The expression `new char(i + 1)` allocates memory for *one* `char` value, and initializes that single value to `i + 1`. You want `new char[i + 1]`. Or better yet, use `std::string`! – Some programmer dude Nov 24 '17 at 14:13
  • 1
    On an unrelated note, the "default" container type should be `std::vector`. Only use e.g. `std::list` if you have very specific requirements. – Some programmer dude Nov 24 '17 at 14:15
  • 1
    Lastly, about the `delete[] tempReader` issue, first of all it's because you don't use `new[]`. Secondly, you can't do it because then you free the memory for the pointer in the list. If you free that memory, then the pointer in the list will not point to any valid memory anymore. – Some programmer dude Nov 24 '17 at 14:17
  • Hi, but if I do not use "delete" I will be declaring a new pointer at each cycle, creating a memory leak, shouldn't try to avoid this? regarding list vs vector, I thought list was more robust being formed with non adjacent registers in memory, is this assumption false? thank you for the prompt reply – bjorn Nov 24 '17 at 14:21
  • You should free the memory when you're *done* with it. Or use `std::string` as I noted before. – Some programmer dude Nov 24 '17 at 14:23
  • "Hi, but if I do not use "delete" I will be declaring a new pointer at each cycle, creating a memory leak, shouldn't try to avoid this?" You most definitely should, **by using std::string**. – n. m. could be an AI Nov 24 '17 at 14:26
  • Ok I believe I'm seeing some light. Unfortunately for this commission I cannot use `std::string` (I actually hate working with `char` arrays). Initializing the Array the way you specified in the first comment solved the memory issue, and that's great! it also made each element in the list hold the correct amount of information. When I tried to delete `tempReader` outside of the while the compiler said it was out of scope, so it is not behaving like a dynamically allocated variable but rather like a local variable, is this correct? – bjorn Nov 24 '17 at 14:29
  • "I thought list was more robust being formed with non adjacent registers in memory" No. – n. m. could be an AI Nov 24 '17 at 14:29
  • 1
    "I cannot use std::string" You should create a custom string class and use it then. – n. m. could be an AI Nov 24 '17 at 14:31
  • @n.m. hi, what kind of issues can a `list` rise versus `vector`? Can you please post a resource I could study? – bjorn Nov 24 '17 at 14:33
  • `list` It is simply inefficient compared to `vector`. – n. m. could be an AI Nov 24 '17 at 14:35
  • ok, and what could be in this case the proper way of using `std::string` to assign the string of characters between the inital `char` of the char array and the nearest `null` character? – bjorn Nov 24 '17 at 14:40
  • Ok silly question, CStrings are by definitions `\0` terminated so it is sufficient to call `std::string::assign(mszReaders)` to get the desired behavior – bjorn Nov 24 '17 at 14:44
  • @bjorn I believe this is a good starting point for your resource https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – UKMonkey Nov 24 '17 at 15:52
  • Possible duplicate of [Error: free(): invalid next size (fast):](https://stackoverflow.com/questions/4729395/error-free-invalid-next-size-fast) – Raedwald Nov 22 '18 at 09:10

0 Answers0