Solved

how do i log file in C++

Posted on 2014-12-26
10
289 Views
Last Modified: 2014-12-29
though im unfamilar with C++ & finally i have wrote such code like following with the refeneces of web,but i has failded,the program has been stoke & memory leak,i just cant figure out why

with the web page
https://gist.github.com/To0ki3/3886428
i add this hpp to my program,however it's memory leak,but if i commet the log file code,my program back to normal and works fine,in addition, Is there any problem that i used for a webservice to call this dll?im very concern the memory leak or other exception.im using vs 2013 paid version .

#1 cpgetadd.h
extern "C"
{
      __declspec(dllexport) int  __stdcall callwebaddr(const char * theurl);
}

//#2 cpgetadd.cpp
#include <stdio.h>
#include <curl/curl.h>
#include "cpgetadd.h"
#include <fstream>
#include<string>
#include "FileLogger.hpp"


#pragma comment(lib,"libcurldll.a")

using namespace std;

void write_text_to_log_file(const std::string &text);

int  __stdcall callwebaddr(const char * theurl)
{
      CURL *curl;
      CURLcode res;

      curl = curl_easy_init();
      if (curl)
      {
            curl_easy_setopt(curl, CURLOPT_URL, theurl);
            /* example.com is redirected, so we tell libcurl to follow redirection */
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

            /* Perform the request, res will get the return code */
            res = curl_easy_perform(curl);
            /* Check for errors */
            if (res != CURLE_OK)
            {
            //      fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
            //the follwing code will comes memory leak if i uncomment it      
            /*      ige::FileLogger myLog("1.0.4.2", "testfile.txt");

                  // Writing warnings or errors to file is very easy and C++ style
                  size_t slen=strlen(curl_easy_strerror(res))+1;
                  size_t  slenwadd = strlen(theurl) + 1;
                  char * errstr = new char[slen + slenwadd];
                  strcpy_s(errstr, slenwadd, theurl);
                  strcat_s(errstr, slen, curl_easy_strerror(res));
                  myLog << ige::FileLogger::e_logType::LOG_ERROR << errstr;
                  delete[] errstr;*/
                  curl_easy_cleanup(curl);
                  return -1;
            }
            else
            {
                    //the follwing code will comes memory leak if i uncomment it      
      /*            ige::FileLogger myLog("1.0.4.2", "testfile.txt");
                  size_t slenwadd = strlen(theurl) + 1;
            char * errstr = new char[ slenwadd + 8];
                  strcpy_s(errstr, slenwadd, theurl);
                  strcat_s(errstr,7, "success");
                  myLog << errstr;
                  delete[] errstr;
            */

                  curl_easy_cleanup(curl);
                  return 0;
            }

      }
       //the follwing code will comes memory leak if i uncomment it      
      /*ige::FileLogger myLog("1.0.4.2", "testfile.txt");
      size_t slenwadd = strlen(theurl) + 1;
      char * errstring = "initial failed";
      size_t slenstr = strlen(errstring) + 1;
      char * errstr = new char[slenwadd + slenstr];
      strcpy_s(errstr, slenwadd, theurl);
      strcat_s(errstr, slenstr,errstring);
      myLog << ige::FileLogger::e_logType::LOG_ERROR << errstr;
      delete[] errstr;
      delete[] errstring;*/
      return -2;

}

/*this is my another version of log file function,it occured error in std::end when i compile it,i just dont know how to resolve it.*/
/*
void write_text_to_log_file(const std::string &text)
{
      std::ofstream log_file(
            "log_file.txt", std::ios_base::out | std::ios_base::app);
      log_file << text << std::end;
}
*/

many thanks
best regards & happy new year
ken
0
Comment
Question by:ken yup
  • 5
  • 3
  • 2
10 Comments
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Did you mean std::endl ?
0
 

Author Comment

by:ken yup
Comment Utility
look at this:
http://www.codeproject.com/Questions/97485/how-to-write-log-file-in-C
i copy the code from here,but it doesnt works
0
 

Author Comment

by:ken yup
Comment Utility
the function of "void write_text_to_log_file(const std::string &text)" i copy from codeproject
0
 
LVL 84

Assisted Solution

by:ozo
ozo earned 125 total points
Comment Utility
It looks like they meant to say endl too.
0
 

Author Comment

by:ken yup
Comment Utility
ok,i'll try to change it,thanks
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 375 total points
Comment Utility
however it's memory leak,but if i commet the log file my program back to normal and works fine
the code has much more problems than memory leaks. it is a mix of c and c++ where neither the one nor the other is used with care.

generally, if using std::string and std::ostream, you don't need to create char pointers or use functions like strcpy, strcpy_s, strcat, strlen, ....

if you don't use 'new' operator you won't create heap memory yourself and because of that your code would not have memory leaks.

(1) always initialize variables:

 
CURL *curl = NULL;
 CURLcode res = CURLE_OK;

Open in new window


(2) the logging code should be turned like that:

 ige::FileLogger myLog("1.0.4.2", "testfile.txt");

// Writing warnings or errors to file is very easy and C++ style
myLog << ige::FileLogger::e_logType::LOG_ERROR << "|" << curl_easy_strerror(res) << "|" << theurl << std::endl;

Open in new window


if the code throws an exception, you may check whether curl_easy_strerror(res) returns a non-null char pointer and whether theurl is valid.

generally, for c++ streams you don't need any helper char arrays or string concatenation. simply use the operator<< to add.

Sara
0
 

Author Comment

by:ken yup
Comment Utility
thank you for your opinions,because i make this dll for powerbuilder legacy version,char * variable is equal string variable in powerbuilder,so i have to use char *,however char * is a C-style character.however i confuse with c & c++,i dont know how to write a dll for powerbuilder correctly.what should be aware.of course my knowledge of c++ is still not enough
0
 
LVL 32

Accepted Solution

by:
sarabande earned 375 total points
Comment Utility
char * variable is equal string variable in powerbuilde
char * is a pointer to char. if it points to 1st element of a char array which has a zero-element to terminate the string it can be used instead of const std::string& because std::string has a constructor that takes a const char* as argument. additionally std::string has a member function c_str(), which you can use whenever a function needs a const char* type as argument or for the right side of an assignment. if a function needs a (writeable) char * buffer, you may do the following:

// define a string variable 
std::string strvar = "whatever value";
// resize it to maximum size needed.
strvar.resize(512); 
// call function that needs char* argument
function_requiring_writeable_char_pointer(&strvar[0], 512);
strvar.resize(strlen(strvar.c_str()));

Open in new window


Sara
0
 

Author Comment

by:ken yup
Comment Utility
from your opinion i have another question:
as you metioned, i wrote the API code mixed with c & c++ sytanx,do you mean i should write the API in pure-C sytanx?
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 375 total points
Comment Utility
i should write the API in pure-C sytanx?
i would recommend against that beside your requirement is to call the api from pure (ansi) c environments, what means that the projects were built by using c compiler rather than c++ compiler (what rarely is the case for nowadays projects). for all other projects an API using stl types as arguments (instead of pointers to arrays) is the better choice.

Sara
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Navigation is an important part of web design from a usability perspective. But it is often a pain when it comes to a developer’s perspective. By navigation, it often means menuing. This is less theory and more practical of how to get a specific gro…
The viewer will learn how to implement Singleton Design Pattern in Java.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now