I am trying to create Linked list in c++ using class. I used only two methods for it that is pushFront() and traverse() to push the new element in the head of the linked list and display the elements in the list at any given time. Whenever i use traverse method i am getting the error "Segmentation fault"
My code is shown below. I looked up about this error in this site and elsewhere. Segmentation fault is said to occur when we attempt to access variable which is not ours to take. i.e it is is space which is not accesible to us. But as one can see in my code I am attempting to use head and tail the private members of the class. But i am using them in the methods of the class themselves. So i should be allowed to do that right? I don't know where am i going wrong with this.
#include <iostream>
using namespace std;
struct Node
{
int data;
Node * next;
};
class LinkedList
{
private:
Node * head;
Node * tail;
public:
LinkedList();
void pushFront(int i);
void traverse();
};
LinkedList::LinkedList()
{
Node * head = NULL;
Node * tail = NULL;
}
void LinkedList::pushFront(int i)
{
Node * newNode =new Node;
newNode->data=i;
newNode->next=head;
head=newNode;
if(tail==NULL)
tail = head;
}
void LinkedList::traverse()
{
if (head==NULL){
cout<<"empty list. add elements";
return;
}
Node * ptr = head;
while(ptr!=NULL)
{
cout<<ptr->data;
ptr=ptr->next;
}
}
int main()
{
LinkedList l;
l.pushFront(10);
l.pushFront(9);
l.traverse();
return 0;
}
I expect that output should be 910 as should be printed by traverse. But i get the segmentation fault error. Can anyone point out where i am wrong?
LinkedList::LinkedList()
{
Node * head = NULL;
Node * tail = NULL;
}
must be (minimal change) :
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
}
else you do not initialize the right attributes but local variables
I encourage you to compile to produce all the warnings, if I compile your code with g++ -Wall -pedantic c.cc this gives
c.cc: In constructor 'LinkedList::LinkedList()':
c.cc:20: warning: unused variable 'head'
c.cc:21: warning: unused variable 'tail'
and this is exactly where the problem is
and about valgrind, if I execute under it that gives :
valgrind ./a.out
==18508== Memcheck, a memory error detector
==18508== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==18508== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==18508== Command: ./a.out
==18508==
==18508== Conditional jump or move depends on uninitialised value(s)
==18508== at 0x400829: LinkedList::pushFront(int) (c.cc:29)
==18508== by 0x4008C2: main (c.cc:48)
==18508==
==18508== Conditional jump or move depends on uninitialised value(s)
==18508== at 0x40089A: LinkedList::traverse() (c.cc:39)
==18508== by 0x4008DF: main (c.cc:50)
==18508==
==18508== Use of uninitialised value of size 8
==18508== at 0x400876: LinkedList::traverse() (c.cc:41)
==18508== by 0x4008DF: main (c.cc:50)
==18508==
==18508== Use of uninitialised value of size 8
==18508== at 0x400888: LinkedList::traverse() (c.cc:42)
==18508== by 0x4008DF: main (c.cc:50)
==18508==
==18508== Invalid read of size 4
==18508== at 0x400876: LinkedList::traverse() (c.cc:41)
==18508== by 0x4008DF: main (c.cc:50)
==18508== Address 0x4b43415254475542 is not stack'd, malloc'd or (recently) free'd
==18508==
==18508==
==18508== Process terminating with default action of signal 11 (SIGSEGV)
==18508== General Protection Fault
==18508== at 0x400876: LinkedList::traverse() (c.cc:41)
==18508== by 0x4008DF: main (c.cc:50)
9101778121006==18508==
==18508== HEAP SUMMARY:
==18508== in use at exit: 32 bytes in 2 blocks
==18508== total heap usage: 2 allocs, 0 frees, 32 bytes allocated
==18508==
==18508== LEAK SUMMARY:
==18508== definitely lost: 0 bytes in 0 blocks
==18508== indirectly lost: 0 bytes in 0 blocks
==18508== possibly lost: 0 bytes in 0 blocks
==18508== still reachable: 32 bytes in 2 blocks
==18508== suppressed: 0 bytes in 0 blocks
==18508== Rerun with --leak-check=full to see details of leaked memory
==18508==
==18508== For counts of detected and suppressed errors, rerun with: -v
==18508== Use --track-origins=yes to see where uninitialised values come from
==18508== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 6 from 6)
Segmentation fault
so you see also the head and tail are not initialized etc
Related
I'm a new C++ coder and met a problem.
Please view the following code as an example:
#include <iostream>
#include <vector>
#include <thread>
class student{
public:
std::string name;
int id;
};
void foo(){
int k = 1;
std::cout<<"thread a"<<std::endl;
return;
}
void foo2(){
int k = 1;
std::cout<<"thread b"<<std::endl;
return;
}
void foo3(){
std::thread a(foo);
std::thread b(foo2);
a.detach();
b.detach();
return;
}
int main(){
foo3();
return 0;
}
That's an example code. I want two threads running independently and release memory after each one ends. I use valgrind to check memory leak. It shows an error like this:
==63346== Memcheck, a memory error detector
==63346== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==63346== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==63346== Command: ./a.out
==63346==
==63346==
==63346== HEAP SUMMARY:
==63346== in use at exit: 608 bytes in 4 blocks
==63346== total heap usage: 5 allocs, 1 frees, 73,312 bytes allocated
==63346==
==63346== 288 bytes in 1 blocks are possibly lost in loss record 3 of 4
==63346== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==63346== by 0x40147D9: calloc (rtld-malloc.h:44)
==63346== by 0x40147D9: allocate_dtv (dl-tls.c:375)
==63346== by 0x40147D9: _dl_allocate_tls (dl-tls.c:634)
==63346== by 0x4B4D834: allocate_stack (allocatestack.c:430)
==63346== by 0x4B4D834: pthread_create##GLIBC_2.34 (pthread_create.c:647)
==63346== by 0x494A388: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30)
==63346== by 0x1095B9: std::thread::thread<void (&)(), , void>(void (&)()) (in /home/alan/Avionics/test/a.out)
==63346== by 0x10935C: foo3() (in /home/alan/Avionics/test/a.out)
==63346== by 0x109400: main (in /home/alan/Avionics/test/a.out)
==63346==
==63346== 288 bytes in 1 blocks are possibly lost in loss record 4 of 4
==63346== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==63346== by 0x40147D9: calloc (rtld-malloc.h:44)
==63346== by 0x40147D9: allocate_dtv (dl-tls.c:375)
==63346== by 0x40147D9: _dl_allocate_tls (dl-tls.c:634)
==63346== by 0x4B4D834: allocate_stack (allocatestack.c:430)
==63346== by 0x4B4D834: pthread_create##GLIBC_2.34 (pthread_create.c:647)
==63346== by 0x494A388: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30)
==63346== by 0x1095B9: std::thread::thread<void (&)(), , void>(void (&)()) (in /home/alan/Avionics/test/a.out)
==63346== by 0x109372: foo3() (in /home/alan/Avionics/test/a.out)
==63346== by 0x109400: main (in /home/alan/Avionics/test/a.out)
==63346==
==63346== LEAK SUMMARY:
==63346== definitely lost: 0 bytes in 0 blocks
==63346== indirectly lost: 0 bytes in 0 blocks
==63346== possibly lost: 576 bytes in 2 blocks
==63346== still reachable: 32 bytes in 2 blocks
==63346== suppressed: 0 bytes in 0 blocks
==63346== Reachable blocks (those to which a pointer was found) are not shown.
==63346== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==63346==
==63346== For lists of detected and suppressed errors, rerun with: -s
==63346== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
If i replace detach() by join(), there's no memory leak, I'm a little confused. Does anyone can give me some advice? Thanks a lot!
You need to make your main wait until the threads have finished running (or at least that they won't access any global objects after). If you don't make sure of that, not only will you have memory leaks, you may also have undefined behavior.
join does exactly make sure of that. The thread calling it will wait until the thread on which join is called finishes.
On the other hand detach is used to when you don't want to keep the std::thread object around to call join on it, while still having the thread function continue to run. If you detach a thread you need to use some other synchronization mechanism outside the join mechanism to make sure that main doesn't exit while the threads are still doing work (or at least accessing global objects).
There is rarely a need to detach a thread. Making it work is complicated. You don't need to do that.
Instead store the std::thread object somewhere and call join on it when you want to wait for your threads to end, at latest before main returns. That should be the default approach if you don't have a good reason to not use it. If you are a beginner, then you can forget about detach for now.
I'm testing c++17 shared_ptr to see how it handles array delete[], but it failed expectation.
First, c++17 document says shared_ptr<T[]> can handle delete[] properly.
http://eel.is/c++draft/util.smartptr.shared#const-5
Effects: When T is not an array type, constructs a shared_ptr object that owns the pointer p. Otherwise, constructs a shared_ptr that owns p and a deleter of an unspecified type that calls delete[] p.
And reset():
http://eel.is/c++draft/util.smartptr.shared#mod-3
Equivalent to shared_ptr(p).swap(*this).
It will transfer the specification-required custom delete. So from my understanding, pre-c++17 I have to write like this:
shared_ptr<int> t1(new int[7], default_delete<int[]>());
Now it knows when 1st parameter is array type, compiler will generate call to delete [], so that we no longer have to specify delete function explicitly. I had a quick test on Ubuntu20.04 with clang++13:
int main() {
shared_ptr<int> t1(new int[7], default_delete<int[]>());
return 0;
}
Then clang++ mytest.cpp && valgrind ./a.out, no problem. But if I change to:
int main() {
shared_ptr<int> t1(new int[7]);
return 0;
}
Then clang++ mytest.cpp -std=c++17 && valgrind ./a.out will print:
==16407== Command: ./a.out
==16407==
Father
1
==16407== Mismatched free() / delete / delete []
==16407== at 0x483CFBF: operator delete(void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==16407== by 0x40450A: std::_Sp_counted_ptr<int*, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (in /home/troskyv/a.out)
==16407== by 0x4030A2: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (in /home/troskyv/a.out)
==16407== by 0x403059: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in /home/troskyv/a.out)
==16407== by 0x403998: std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in /home/troskyv/a.out)
==16407== by 0x4020C4: std::shared_ptr<int>::~shared_ptr() (in /home/troskyv/a.out)
==16407== by 0x40152E: main (in /home/troskyv/a.out)
==16407== Address 0x4db34c0 is 0 bytes inside a block of size 28 alloc'd
==16407== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==16407== by 0x4014F7: main (in /home/troskyv/a.out)
==16407==
==16407==
==16407== HEAP SUMMARY:
==16407== in use at exit: 0 bytes in 0 blocks
==16407== total heap usage: 15 allocs, 15 frees, 74,032 bytes allocated
==16407==
==16407== All heap blocks were freed -- no leaks are possible
==16407==
==16407== For lists of detected and suppressed errors, rerun with: -s
==16407== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
There's memory leak. So seems to me although I used -std=c++17 option, shared_ptr still cannot handle delete array automatically.
Where did this get wrong?
I see the answer is difference between shared_ptr<int> and shared_ptr<int[]>. Use of the latter one avoids memory leak.
Thanks, close this question!
I'm learn about std::allocator. I try to allocate but use deallocate incorrectly I saw that it didn't use size argument, I confuse about the method could you please explain for me ? Thanks.
testcase1 "test" : I didn't deallocate, valgrind detected (correct)
testcase2 "test_deallocate" : I deallocate with size(0) less than actual size (400),valgrind or -fsanitize=address can't detect leak
testcase3 "test_deallocate2": I deallocate with size(10000) greater than actual size (400) compiler didn't warning , g++ with -fsanitize=address also can't detect this.
#include <iostream>
#include <memory>
using namespace std;
void test(){
allocator<int> al;
int* bl = al.allocate(100);
}
void test_deallocate(){
allocator<int> al;
int* bl = al.allocate(100);
al.deallocate(bl, 0);
}
void test_deallocate2(){
allocator<int> al;
int* bl = al.allocate(100);
al.deallocate(bl, 10000);
}
int main(){
test();
test_deallocate();
test_deallocate2();
return 0;
}
Valgrind:
valgrind --leak-check=full ./a.out
==12655== Memcheck, a memory error detector
==12655== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12655== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==12655== Command: ./a.out
==12655==
==12655==
==12655== HEAP SUMMARY:
==12655== in use at exit: 400 bytes in 1 blocks
==12655== total heap usage: 4 allocs, 3 frees, 73,904 bytes allocated
==12655==
==12655== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12655== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12655== by 0x1090D1: allocate (new_allocator.h:114)
==12655== by 0x1090D1: test (test.cpp:8)
==12655== by 0x1090D1: main (test.cpp:27)
==12655==
==12655== LEAK SUMMARY:
==12655== definitely lost: 400 bytes in 1 blocks
==12655== indirectly lost: 0 bytes in 0 blocks
==12655== possibly lost: 0 bytes in 0 blocks
==12655== still reachable: 0 bytes in 0 blocks
==12655== suppressed: 0 bytes in 0 blocks
==12655==
==12655== For lists of detected and suppressed errors, rerun with: -s
==12655== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Valgrind only intercepts the lower level allocation functions (malloc, new etc.). So it all depends on what the implementation of allocate and deallocate do.
Currently Valgrind doesn't do much checking of sized delete (or aligned new for that matter, see why does std::allocator::deallocate require a size? and https://bugs.kde.org/show_bug.cgi?id=433859).
I may implement something for these in 2022.
If you use GCC libstdc++ or clang libc++ then their sized deletes do not do anything special, they just call plain delete. I haven't looked for deallocate.
testcase2 "test_deallocate" : I deallocate with size(0) less than actual size (400),valgrind or -fsanitize=address can't detect leak
When you dellocate with wrong size, then the behaviour of the program is undefined. When the behaviour is undefined, there is no guarantee that memory would be leaked.
testcase3 "test_deallocate2": I deallocate with size(10000) greater than actual size (400) compiler didn't warning , g++ with -fsanitize=address also can't detect this.
Ditto.
I checked libstdc++ which used in the testcases.
I saw that currently size argument for std::allocator::deallocate is unused. it call delete, same with new/delete operator operation, it don't need size anymore.
00096 void
00097 deallocate(pointer __p, size_type)
00098 { ::operator delete(__p); }
https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00958_source.html
I am writing a function which calls Fortran functions for complex matrix matrix multiplication. I am calling the CGEMM_ and ZGEMM_ functions for complex multiplication. Since all xGEMM_ functions are essentially the same I copied the code from SGEMM_ to CGEMM__ and ZGEMM_. The only change made were the respective data types. The SGEMM_ and DGEMM_ functions are working fine but CGEMM_ throws the error. All inputs are the same as well.
** On entry to CGEMM parameter number 13 had an illegal value
and zgemm_ throws
** On entry to ZGEMM parameter number 1 had an illegal value
I really have no idea what's going on. Is this some kind of bug in the liblapack package? I am using liblapack-dev package. I made a smaller version of my big code and i am still getting the same error with CGEMM_.
I am running a 32-bit system and was wondering if that was the problem.
Code:
#include<iostream>
using namespace std;
#include<stdlib.h>
#include<string.h>
#include<complex>
typedef complex<float> c_float;
extern "C"
{c_float cgemm_(char*,char*,int*,int*,int*,c_float*, c_float[0],int*,c_float[0],int*,c_float*,c_float[0],int*);//Single Complex Matrix Multiplication
}
c_float** allocate(int rows, int columns)
{
c_float** data;
// Allocate Space
data = new c_float*[columns]; //Allocate memory for using multidimensional arrays in column major format.
data[0] = new c_float[rows*columns];
for (int i=0; i<columns; i++)
{
data[i] = data[0] + i*rows;
}
// Randomize input
for (int i=0; i<columns; i++)
{for (int j=0; j<rows; j++)
{
data[j][i] =complex<double>(drand48()*10 +1,drand48()*10 +1); //Randomly generated matrix with values in the range [1 11)
}
}
return(data);
}
// Destructor
void dest(c_float** data)
{
delete [] data[0];
delete [] data;
}
// Multiplication
void mult(int rowsA,int columnsA, int rowsB,int columnsB)
{
c_float **matA,**matB,**matC;
char transA, transB;
int m,n,k,LDA,LDB,LDC;
c_float *A,*B,*C;
c_float alpha(1.0,0.0);
c_float beta(0.0,0.0);
matA = allocate(rowsA,columnsA);
matB = allocate(rowsB,columnsB);
matC = allocate(rowsA,columnsB);
transA = 'N';
transB = 'N';
A = matA[0];
B = matB[0];
m = rowsA;
n = columnsB;
C = matC[0];
k = columnsA;
LDA = m;
LDB = k;
LDC = m;
cout<<"Matrix A"<<endl;
for (int i=0; i<rowsA; i++)
{for (int j=0; j<columnsA; j++)
{
cout<<matA[i][j];
cout<<" ";
}cout<<endl;
}
cout<<"Matrix B"<<endl;
for (int i=0; i<rowsB; i++)
{for (int j=0; j<columnsB; j++)
{
cout<<matB[i][j];
cout<<" ";
}cout<<endl;
}
cgemm_(&transA,&transB,&m,&n,&k,&alpha,A,&LDA,B,&LDB,&beta,C,&LDC);
cout<<"Matrix A*B"<<endl;
for (int i=0; i<rowsA; i++)
{for (int j=0; j<columnsB; j++)
{
cout<<matC[i][j];
cout<<"";
}
cout<<endl;
}
dest(matA);
dest(matB);
dest(matC);
}
main()
{
mult (2,2,2,2);
}
The output and valgrind report are as follows:
-----------------------------------------
Compilation using g++ -g -o matrix Matrix_multiplication.cpp -lblas -llapack -lgfortran
./matrix gives
Matrix A
(1.00985,1) (1.91331,4.64602)
(2.76643,1.41631) (5.87217,1.92298)
Matrix B
(5.54433,6.2675) (6.6806,10.3173)
(9.31292,3.33178) (1.50832,6.56094)
** On entry to CGEMM parameter number 1 had an illegal value
Valgrind output looks like
==4710== Memcheck, a memory error detector
==4710== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4710== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4710== Command: ./o
==4710== Parent PID: 3337
==4710==
==4710== Conditional jump or move depends on uninitialised value(s)
==4710== at 0x46E5096: lsame_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x46DD683: cgemm_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x8048C7E: mult(int, int, int, int) (Matrix_multiplication.cpp:83)
==4710== by 0x8048D70: main (Matrix_multiplication.cpp:102)
==4710== Uninitialised value was created by a stack allocation
==4710== at 0x8048A18: mult(int, int, int, int) (Matrix_multiplication.cpp:43)
==4710==
==4710== Conditional jump or move depends on uninitialised value(s)
==4710== at 0x46DD686: cgemm_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x8048C7E: mult(int, int, int, int) (Matrix_multiplication.cpp:83)
==4710== by 0x8048D70: main (Matrix_multiplication.cpp:102)
==4710== Uninitialised value was created by a stack allocation
==4710== at 0x8048A18: mult(int, int, int, int) (Matrix_multiplication.cpp:43)
==4710==
==4710== Conditional jump or move depends on uninitialised value(s)
==4710== at 0x46E5096: lsame_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x46DD7B1: cgemm_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x8048C7E: mult(int, int, int, int) (Matrix_multiplication.cpp:83)
==4710== by 0x8048D70: main (Matrix_multiplication.cpp:102)
==4710== Uninitialised value was created by a stack allocation
==4710== at 0x8048A18: mult(int, int, int, int) (Matrix_multiplication.cpp:43)
==4710==
==4710== Conditional jump or move depends on uninitialised value(s)
==4710== at 0x46DD7B4: cgemm_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x8048C7E: mult(int, int, int, int) (Matrix_multiplication.cpp:83)
==4710== by 0x8048D70: main (Matrix_multiplication.cpp:102)
==4710== Uninitialised value was created by a stack allocation
==4710== at 0x8048A18: mult(int, int, int, int) (Matrix_multiplication.cpp:43)
==4710==
==4710== Conditional jump or move depends on uninitialised value(s)
==4710== at 0x46E5096: lsame_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x46DD859: cgemm_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x8048C7E: mult(int, int, int, int) (Matrix_multiplication.cpp:83)
==4710== by 0x8048D70: main (Matrix_multiplication.cpp:102)
==4710== Uninitialised value was created by a stack allocation
==4710== at 0x8048A18: mult(int, int, int, int) (Matrix_multiplication.cpp:43)
==4710==
==4710== Conditional jump or move depends on uninitialised value(s)
==4710== at 0x46DD85C: cgemm_ (in /usr/lib/atlas-base/atlas/libblas.so.3.0)
==4710== by 0x8048C7E: mult(int, int, int, int) (Matrix_multiplication.cpp:83)
==4710== by 0x8048D70: main (Matrix_multiplication.cpp:102)
==4710== Uninitialised value was created by a stack allocation
==4710== at 0x8048A18: mult(int, int, int, int) (Matrix_multiplication.cpp:43)
==4710==
==4710==
==4710== HEAP SUMMARY:
==4710== in use at exit: 120 bytes in 6 blocks
==4710== total heap usage: 43 allocs, 37 frees, 13,897 bytes allocated
==4710==
==4710== LEAK SUMMARY:
==4710== definitely lost: 0 bytes in 0 blocks
==4710== indirectly lost: 0 bytes in 0 blocks
==4710== possibly lost: 0 bytes in 0 blocks
==4710== still reachable: 120 bytes in 6 blocks
==4710== suppressed: 0 bytes in 0 blocks
==4710== Rerun with --leak-check=full to see details of leaked memory
==4710==
==4710== For counts of detected and suppressed errors, rerun with: -v
==4710== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
EDIT: The question was modified with a code that can be run. The problem remains the same and the nature of the question has not changed.
The answer about the length of character variables in Fortran is essentially correct, but that is not your problem here. Fixed length character variables of functions inside the blas library will probably not read the length from a function argument. I checked this for a function and even at -O0 the length was a compile-time constant.
The cause of your particular problem is the definition c_float cgemm_(..., where you tell the compiler that cgemm_ returns a c_float. Normally, return values are put in a register, but when they are too large they can also go on the stack. In your case, on a 32bit system, this seems to be the case for the 8-byte c_float. Defining the function to be void cgemm_ (as it should be) or even int cgemm_ (which will use a register) solves the issue.
The take-home message is "don't do this", as this is a hackish way of calling and will cause headaches when dealing with different platforms/compilers. It is much better to use the cblas interface, or a C++ library for blas operations.
I don't see the lengths of the transA or transB strings being passed to the xgemm_ call.
Character dummies in Fortran are accompanied by a 'hidden' length argument. The convention used by GCC 4.9.0, for example, for this is described more here:
https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/Argument-passing-conventions.html.
The positioning of these hidden arguments in the argument list is platform dependent. On Linux they are placed after all the explicit arguments.
Consider s.f90
Subroutine s(c, r)
Character (*), Intent (In) :: c
Real, Intent (In) :: r
Print '(3A,I0,A)', 'c = "', c, '", (len(c)=', len(c), ')'
Print *, 'r = ', r
End Subroutine
and main.c
#include <string.h>
int main(void)
{
char c[1+1];
float r=4.2;
strcpy(c,"A");
s_(c,&r,1);
}
For running on Linux I am passing 1 as the (hidden in Fortran) third argument for s, representing the length of my string.
Compiling and running with gfortran gives me
> gfortran -g main.c s.f90 && ./a.out
c = "A", (len(c)=1)
r = 4.19999981
So probably your xgemm_ calls should be ...,&LDC,1,1);?
I have a program like this:
int *number0 = new int;
int main()
{
int *number1 = new int;
}
I thought, both memory allocations would introduce memory leaks, though valgrind only
complains about number1 inside the main function. Why is that?
Running this
int *x = new int;
int main()
{
return 0;
}
code (i.e without the leak in the main, compiled with g++ 4.8.1) using valgrind (3.8.1) with (-v --track-origins=yes --leak-check=full --show-reachable=yes) I get:
==34301==
==34301== HEAP SUMMARY:
==34301== in use at exit: 4 bytes in 1 blocks
==34301== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==34301==
==34301== Searching for pointers to 1 not-freed blocks
==34301== Checked 189,064 bytes
==34301==
==34301== 4 bytes in 1 blocks are still reachable in loss record 1 of 1
==34301== at 0x4C2A879: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==34301==
==34301== LEAK SUMMARY:
==34301== definitely lost: 0 bytes in 0 blocks
==34301== indirectly lost: 0 bytes in 0 blocks
==34301== possibly lost: 0 bytes in 0 blocks
==34301== still reachable: 4 bytes in 1 blocks
==34301== suppressed: 0 bytes in 0 blocks
Which means that you should also pay attention to the in use at exit category.
It doesn't seem like valgrind missed it, just placed it in another category, possibly because they assume something as lost only when you cannot by any means track down that address and release it, but this variable is never lost.
This however :
int *x = new int;
int main()
{
x = new int;
return 0;
}
Is detected as a leak as you really lose track of the memory you've allocated.
EDIT: As described in the Mem-check manual:
"Still reachable". This covers cases 1 and 2 (for the BBB blocks)
above. A start-pointer or chain of start-pointers to the block is
found. Since the block is still pointed at, the programmer could, at
least in principle, have freed it before program exit. "Still
reachable" blocks are very common and arguably not a problem. So, by
default, Memcheck won't report such blocks individually.
So as noted before they do detect it, they just think it's less exciting
Valgrind is not a perfect tool for detecting the presence or absence of all possible memory leaks, but rather a helpful tool that can detect some memory leaks. This means that valgrind output cannot be used to determine whether a particular piece of code contains or does not contain any leaks.
Neither of your news have corresponding deletes, and in that sense, they are both leaked.
It is likely that valgrind considers the number0 memory to not be leaked because the memory it points to is reachable at the end of the program execution. In contrast to this, number1 goes out of scope, and so the memory it points to is not reachable at the end of the execution of your program, and so valgrind considers it to be leaked.
I see two leaks using valgrind 3.8.1 / g++ 4.8.1:
$ g++ -o foo -g foo.cc
$ valgrind ./foo
...
==7789== HEAP SUMMARY:
==7789== in use at exit: 8 bytes in 2 blocks
==7789== total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==7789==
==7789== LEAK SUMMARY:
==7789== definitely lost: 4 bytes in 1 blocks
==7789== indirectly lost: 0 bytes in 0 blocks
==7789== possibly lost: 0 bytes in 0 blocks
==7789== still reachable: 4 bytes in 1 blocks
==7789== suppressed: 0 bytes in 0 blocks
The "definitely lost" bytes are in main in my test.
This
int *number0 = new int;
is not a memory leak because it gets reclaimed at the end of execution.
This configuration is a [potential] memory leak because
int main()
{
int *number1 = new int;
}
some other part of the code could call
main () ;
and it could be called repeatedly.