{"id":454,"date":"2022-08-30T15:01:37","date_gmt":"2022-08-30T15:01:37","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/simple-test-of-malloc-and-free-with-int-pointer-causes-double-free-or-corruption-error-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:01:37","modified_gmt":"2022-08-30T15:01:37","slug":"simple-test-of-malloc-and-free-with-int-pointer-causes-double-free-or-corruption-error-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/simple-test-of-malloc-and-free-with-int-pointer-causes-double-free-or-corruption-error-collection-of-common-programming-errors\/","title":{"rendered":"Simple test of malloc and free with int pointer causes double free or corruption error-Collection of common programming errors"},"content":{"rendered":"<p>To learn more about pointers I wrote just a simple test function which creates a pointer, allocates space ande after some output on the shell the space shall be freed.<\/p>\n<pre><code>void main() {\n  int *p = (int*) malloc(sizeof(int));\n  int a = 42;\n  printf(\"p: %x\\n\", p);\n  printf(\"*p: %d\\n\", *p);\n  printf(\"a: %s\\n\", a);\n  printf(\"&amp;a: %x\\n\", &amp;a);\n  p = &amp;a;\n  printf(\"p: %x\\n\", p);\n  printf(\"*p: %x\\n\", *p);\n\n  \/\/Until now everything works as expected\n  free(p); \/\/ERROR\n  \/\/ printf(\"p: %x\\n\", p); \/\/ Shall cause error, because space was freed\n  \/\/ printf(\"*p: %x\\n\", *p); \/\/ Shall cause error, because space was freed\n}\n<\/code><\/pre>\n<p>At first runs everything was ok. free(p) caused no error. Then I tried the same test with a struct and got the double free error. &#8220;Ok, maybe I do something wrong, lets go to the start&#8221;, I thought and Ctrl+Z everything to this one above, like it was before. Now I still get this error. Why? Thats a newbie question, I know. The code above you can find everywhere in the web as a simple demonstration of malloc and free. Like here: http:\/\/www.cplusplus.com\/reference\/cstdlib\/free\/ Hope, someone can tell me what I do wrong.<\/p>\n<ol>\n<li>\n<p>The pointer passed to <code>free()<\/code> <em>must<\/em> be returned from a previous call to <code>malloc()<\/code> (or <code>calloc()<\/code> or <code>realloc()<\/code>). This is not the case as <code>p<\/code> has the address of <code>a<\/code> after:<\/p>\n<pre><code>p = &amp;a;\n<\/code><\/pre>\n<p>and <code>p<\/code> is then passed to <code>free()<\/code> causing undefined behaviour.<\/p>\n<p>Note that in the example on page linked in the question nowhere is the pointer being reassigned after the call to any of the dynamic allocation functions.<\/p>\n<p>The comment <code>\"Shall cause error, because space was freed\"<\/code> in the following code snippet is incorrect:<\/p>\n<pre><code>free(p); \/\/ERROR\n\/\/ printf(\"p: %x\\n\", p); \/\/ Shall cause error, because space was freed\n<\/code><\/pre>\n<p>as it is safe to print the address of a pointer, regardless of whether the memory it has been associated with has been <code>free()<\/code> or not. It <em>is<\/em> an error if you attempt to access memory that has been <code>free()<\/code>d, so this comment is correct:<\/p>\n<pre><code>\/\/ printf(\"*p: %x\\n\", *p); \/\/ Shall cause error, because space was freed\n<\/code><\/pre>\n<p>because <code>p<\/code> is being deferenced and an attempt to read <code>free()<\/code>d memory is occurring.<\/p>\n<p>This is an error:<\/p>\n<pre><code>printf(\"a: %s\\n\", a); \/* Must be '%d' as 'a' is an 'int'. *\/\n<\/code><\/pre>\n<p>Note that:<\/p>\n<pre><code>printf(\"p: %x\\n\", p);\n<\/code><\/pre>\n<p>is also undefined behaviour: use <code>%p<\/code> format specifier for pointers. See Correct format specifier to print pointer (address)?<\/p>\n<p>Do I cast the result of malloc?<\/p>\n<\/li>\n<li>\n<pre><code>void main() {\n  int *p = (int*) malloc(sizeof(int));   \/\/ here is error number one.\n                                         \/\/ you casted your fresh malloc'd int\n                                         \/\/ to an int*\n                                         \/\/ which is not what you want to do\n                                         \/\/ get rid of the cast you don't need it.\n\n   \/\/ here is where your problem continues.\n  int a = 42;   \/\/ this variable A was created on the stack not the heap!!\n                \/\/you cant free this, which is what you are doing below.\n  printf(\"p: %x\\n\", p);\n  printf(\"*p: %d\\n\", *p);\n  printf(\"a: %s\\n\", a);\n  printf(\"&amp;a: %x\\n\", &amp;a);\n\n  p = &amp;a; \/\/ this is a correct statement. \n          \/\/ you getting the address of var a\n          \/\/ and making pointer p point to A's contents.\n  printf(\"p: %x\\n\", p);\n  printf(\"*p: %x\\n\", *p);\n\n  \/\/Until now everything works as expected\n  free(p); \/\/ERROR: here you are trying to free var A \n           \/\/ but you cant because it wasnt dynamically allocated.\n  \/\/ printf(\"p: %x\\n\", p); \/\/ Shall cause error, because space was freed\n  \/\/ printf(\"*p: %x\\n\", *p); \/\/ Shall cause error, because space was freed\n}\n<\/code><\/pre>\n<p>hope this helps a bit. I highly recommend that you read CH 5 on pointer in K&amp;R(Kernegie and Richie) C programming language book. its really short and you can probly find it free online somewhere. in fact i recommond that you read the whole book. best c book out there. remember you can only free what you malloced (remember each malloc gives you blocks in memory from the heap)<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-11-09 19:43:32. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>To learn more about pointers I wrote just a simple test function which creates a pointer, allocates space ande after some output on the shell the space shall be freed. void main() { int *p = (int*) malloc(sizeof(int)); int a = 42; printf(&#8220;p: %x\\n&#8221;, p); printf(&#8220;*p: %d\\n&#8221;, *p); printf(&#8220;a: %s\\n&#8221;, a); printf(&#8220;&amp;a: %x\\n&#8221;, &amp;a); p [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-454","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=454"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/454\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}