为什么在visual c ++中发布版本的代码中出现语法错误 [英] Why syntax error in release version of code in visual c++

查看:134
本文介绍了为什么在visual c ++中发布版本的代码中出现语法错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地使用libcurl从visual c ++发送电子邮件(在调试模式下),但是当我使用发布模式时,我收到以下错误:

>邮件来自:< xxxx@gmail.com> SIZE = 22322250707370015 
< 555 5.5.2语法错误。 vx10sm168176313pac.17 - gsmtp





我的代码是:

  #include   <   stdio.h  >  
#include < stdlib.h >
#include < string.h >
#include < curl /curl.h>
#include < string > ;
#include < ; cassert >
#include < limit >
#include < stdexcept >
#include < ctime >

#define _WINSOCKAPI_
#include < windows.h >

#define FROM< xxxx@gmail.com>
#define TO< xxxx@gmail.com>
#define FILENAMEedgE0DF.tmp

static const int CHARS = 200 ; // 使用\r,\ n和\0一次发送54个字符,它变为57
static const int ADD_SIZE = 7 ; // ADD_SIZE for TO,FROM,SUBJECT,CONTENT-TYPE,CONTENT-TRANSFER-ENCODING,CONETNT-DISPOSITION和\ r \ n
静态 const int SEND_BUF_SIZE = 54 ;
static char (* fileBuf)[CHARS] = NULL;

struct fileBuf_upload_status
{
int lines_read;
};

static const char b64_table [ 65 ] = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + / ;

static const char reverse_table [ 128 ] = {
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 62 64 64 64 63
52 53 54 55 56 57 58 59 60 61 64 64 64 64 64 64
64 0 1 2 3 4 5 ,< span class =code-digit> 6
7 8 9 10 11 12
13 14
15 16 17 ,< span class =code-digit> 18 , 19 20 21 22 23 24 25 64 64 64 64 64
64 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50 51 64 64 64 64 64
};

std :: string base64_encode( const :: std :: string& bindata)
{
使用 :: std :: string;
使用 :: std :: numeric_limits;

// if(bindata.size()>(numeric_limits< string :: size_type> ; :: max()/ 4u)* 3u){
// throw :: std :: length_error(将字符串太大转换为base64。);
// }

const :: std :: size_t binlen = bindata.size();
// 使用=符号以便正确填充结尾。
string retval ((((binlen + 2 )/ 3 )* 4 ),' =');
:: std :: size_t outpos = 0 ;
int bits_collected = 0 ;
unsigned int accumulator = 0 ;
const string :: const_iterator binend = bindata.end();

for (string :: const_iterator i = bindata.begin(); i!= binend; ++ i){
accumulator =(累加器<< 8 )| (* i& 0xffu);
bits_collected + = 8 ;
while (bits_collected> = 6 ){
bits_collected - = 6 ;
retval [outpos ++] = b64_table [(accumulator>> bits_collected)& 0x3fu];
}
}
如果(bits_collected> 0 ){ // 缺少任何尾随位。
assert(bits_collected< 6 );
accumulator<< = 6 - bits_collected;
retval [outpos ++] = b64_table [accumulator& 0x3fu];
}
断言(outpos> =(retval.size() - 2 ));
断言(outpos< = retval.size());
return retval;
}

size_t read_file()
{
FILE * hFile = NULL;
size_t fileSize( 0 ),len( 0 ),buffer_size( 0 );

// 打开文件
hFile = fopen(FILENAME , rb);
if (hFile == NULL)
throw 文件不存在。;

// 获取文件大小
fseek(hFile,< span class =code-digit> 0
,SEEK_END);
fileSize = ftell(hFile);
fseek(hFile, 0 ,SEEK_SET);
buffer_size + = fileSize;

// 检查文件大小
if (fileSize> 1 * 1024
{}

int no_of_rows = fileSize / SEND_BUF_SIZE + 1 ;
int read( 0 );
fileBuf = new char [ADD_SIZE + no_of_rows + 1 ] [煤焦]; // 我们在条件语句中使用的特殊字符的额外行,这里
// ADD_SIZE for TO,FROM,SUBJECT,CONTENT-TYPE,CONTENT-TRANSFER-ENCODING,CONETNT-DISPOSITION和\ r \
buffer_size + = ADD_SIZE;

strcpy(fileBuf [len ++], To: TO \\\\ nn);
strcpy(fileBuf [len ++], From: FROM \\\\ n);
strcpy(fileBuf [len ++], 主题:SMTP TLS示例消息\\\\ n< /跨度>);
strcpy(fileBuf [len ++], Content-Type:application / x-msdownload; name = \ FILENAME \\\\\ n);
strcpy(fileBuf [len ++], Content-Transfer-Encoding:base64 \\\\ n );
strcpy(fileBuf [len ++], Content-Disposition:attachment; filename = \ FILENAME \\\\\ n);
strcpy(fileBuf [len ++], \\\\ nn);

char * temp_buf = new char [SEND_BUF_SIZE + 4 ]; // 额外大小为4个字节
std :: string encodedStr,temp_buf_str;

for (; len< no_of_rows + ADD_SIZE; ++ len)
{
read = fread(temp_buf) , sizeof char ),SEND_BUF_SIZE,hFile);
temp_buf [read] = ' \0';
temp_buf_str = std :: string(temp_buf);
encodedStr = base64_encode(temp_buf_str);
encodedStr + = \\\\ n;
memcpy(fileBuf [len],encodedStr.c_str(),encodedStr.size()+ 1);
}
strcpy(fileBuf [len], );
return buffer_size;
}

static size_t fileBuf_source( void * ptr, size_t size, size_t nmemb, void * userp)
{
struct fileBuf_upload_status * upload_ctx =( struct fileBuf_upload_status *)userp;
const char * fdata;

if ((size == 0 )||(nmemb == 0 )||((size * nmemb)< 1 ))
{
return 0 ;
}

fdata = fileBuf [upload_ctx-> lines_read];

if (strcmp(fdata, ))
{
size_t len = strlen(fdata);
memcpy(ptr,fdata,len);
upload_ctx-> lines_read ++;
return len;
}
return 0 ;
}

int main()
{
CURL * curl;
CURLcode res = CURLE_OK;
struct curl_slist * recipients = NULL;
struct fileBuf_upload_status file_upload_ctx;
size_t file_size( 0 );

file_upload_ctx.lines_read = 0 ;

curl = curl_easy_init();
file_size = read_file();

if (curl)
{
curl_easy_setopt(curl,CURLOPT_USERNAME, xxxx);
curl_easy_setopt(curl,CURLOPT_PASSWORD, xxxx);
curl_easy_setopt(curl,CURLOPT_URL, smtp://smtp.gmail.com:587);
curl_easy_setopt(curl,CURLOPT_USE_SSL,( long )CURLUSESSL_ALL);
curl_easy_setopt(curl,CURLOPT_CAINFO, google.pem);
curl_easy_setopt(curl,CURLOPT_MAIL_FROM,FROM);
recipients = curl_slist_append(recipients,TO);
curl_easy_setopt(curl,CURLOPT_MAIL_RCPT,收件人);

curl_easy_setopt(curl,CURLOPT_INFILESIZE_LARGE,file_size);
curl_easy_setopt(curl,CURLOPT_READFUNCTION,fileBuf_source);
curl_easy_setopt(curl,CURLOPT_READDATA,& file_upload_ctx);
curl_easy_setopt(curl,CURLOPT_UPLOAD,1L);
curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
}
while true
{
res = curl_easy_perform(curl);
if (res == CURLE_OK)
{
curl_easy_cleanup(curl);
delete [] fileBuf;
break ;
}
睡眠(延迟);
}

system( pause);
return 0 ;
}





任何建议??

解决方案

As在解决方案2中提到,存在一些内存泄漏。由new或new []分配的任何内存都应该分别通过delete(或者delete []来释放。



并且受到该解决方案的启发,你可能会有所不同报告的文件大小和实际所需的大小,如新行和其他空格或部分数据块的确切处理。



添加一些验证应该相对容易检查调试目的。例如,您可以计算文件或块中写入的字节数,并与预期或分配值进行比较。



每次追加之前,您可以验证还有足够的空间。



然后,您可以使用调试器并设置在您要溢出缓冲区时将触发的断点。



你也可以尝试在一个或多个缓冲区中添加一些额外的空间并检查问题是否仍然存在。如果没有,那么可能,你的估计尺寸太小了。然后,您应该验证计算的val在所有情况下都是安全的。


检查fread,fseek和ftell的错误结果 - 这可能会破坏你的文件大小估计。



另外,你有内存泄漏。

 char *  temp_buf   =   new  char [SEND_BUF_SIZE  +  4];  //  额外增加4个字节 

如果没有看到您的代码,我们就无法提供帮助。但是你应该看一下经典的Newcomer文章:Surviving the Release Version [ ^ ]。

I'm successfully able to send email using libcurl from visual c++ (in debug mode), but when I use release mode I'm getting following error:

> MAIL FROM:<xxxx@gmail.com> SIZE=22322250707370015
< 555 5.5.2 Syntax error. vx10sm168176313pac.17 - gsmtp



My code is :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <string>
#include <cassert>
#include <limits>
#include <stdexcept>
#include <ctime>

#define _WINSOCKAPI_
#include <windows.h>

#define FROM    "<xxxx@gmail.com>"
#define TO      "<xxxx@gmail.com>"
#define FILENAME "edgE0DF.tmp"

static const int CHARS= 200;			//Sending 54 chararcters at a time with \r , \n and \0 it becomes 57 
static const int ADD_SIZE= 7;			// ADD_SIZE for TO,FROM,SUBJECT,CONTENT-TYPE,CONTENT-TRANSFER-ENCODING,CONETNT-DISPOSITION and \r\n
static const int SEND_BUF_SIZE= 54;
static char (*fileBuf)[CHARS] = NULL;

struct fileBuf_upload_status 
{
  int lines_read;
};

static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const char reverse_table[128] = {
   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
   64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
   64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64
};

std::string base64_encode(const ::std::string &bindata)
{
   using ::std::string;
   using ::std::numeric_limits;

   //if (bindata.size() > (numeric_limits<string::size_type>::max() / 4u) * 3u) {
   //   throw ::std::length_error("Converting too large a string to base64.");
   //}

   const ::std::size_t binlen = bindata.size();
   // Use = signs so the end is properly padded.
   string retval((((binlen + 2) / 3) * 4), '=');
   ::std::size_t outpos = 0;
   int bits_collected = 0;
   unsigned int accumulator = 0;
   const string::const_iterator binend = bindata.end();

   for (string::const_iterator i = bindata.begin(); i != binend; ++i) {
      accumulator = (accumulator << 8) | (*i & 0xffu);
      bits_collected += 8;
      while (bits_collected >= 6) {
         bits_collected -= 6;
         retval[outpos++] = b64_table[(accumulator >> bits_collected) & 0x3fu];
      }
   }
   if (bits_collected > 0) { // Any trailing bits that are missing.
      assert(bits_collected < 6);
      accumulator <<= 6 - bits_collected;
      retval[outpos++] = b64_table[accumulator & 0x3fu];
   }
   assert(outpos >= (retval.size() - 2));
   assert(outpos <= retval.size());
   return retval;
}

size_t read_file()
{
	FILE* hFile=NULL;
	size_t fileSize(0),len(0),buffer_size(0);

	//opening the file
	hFile = fopen(FILENAME,"rb");
	if (hFile == NULL)
		throw "File Does not exist.";

	//get file size
	fseek(hFile,0,SEEK_END);
	fileSize = ftell(hFile);
	fseek(hFile,0,SEEK_SET);
	buffer_size += fileSize;

	//Checking file size
	if(fileSize > 1*1024)
	{}

	int no_of_rows = fileSize/SEND_BUF_SIZE + 1;
	int read(0);
	fileBuf = new char[ADD_SIZE + no_of_rows + 1][CHARS];	//Extra row for our special character to be used in conditional statements,here ""
											// ADD_SIZE for TO,FROM,SUBJECT,CONTENT-TYPE,CONTENT-TRANSFER-ENCODING,CONETNT-DISPOSITION and \r\n
	buffer_size += ADD_SIZE;

	strcpy(fileBuf[len++],"To: " TO "\r\n");
	strcpy(fileBuf[len++],"From: " FROM "\r\n");
	strcpy(fileBuf[len++],"Subject: SMTP TLS example message\r\n");
	strcpy(fileBuf[len++],"Content-Type: application/x-msdownload; name=\"" FILENAME "\"\r\n");
	strcpy(fileBuf[len++],"Content-Transfer-Encoding: base64\r\n");
	strcpy(fileBuf[len++],"Content-Disposition: attachment; filename=\"" FILENAME "\"\r\n");
	strcpy(fileBuf[len++],"\r\n");

	char* temp_buf = new char[SEND_BUF_SIZE + 4];	//taking extra size of 4 bytes
	std::string encodedStr, temp_buf_str;
	
	for (; len < no_of_rows + ADD_SIZE; ++len)
	{
		read = fread(temp_buf,sizeof(char),SEND_BUF_SIZE,hFile);
		temp_buf[read] ='\0';
		temp_buf_str = std::string(temp_buf);
		encodedStr = base64_encode(temp_buf_str);
		encodedStr += "\r\n";
		memcpy(fileBuf[len],encodedStr.c_str(),encodedStr.size()+1);
	}
	strcpy(fileBuf[len],"");
	return buffer_size;
}

static size_t fileBuf_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
	struct fileBuf_upload_status *upload_ctx = (struct fileBuf_upload_status *)userp;
	const char *fdata;

	if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) 
	{
		return 0;
	}

	fdata = fileBuf[upload_ctx->lines_read];

	if(strcmp(fdata,"")) 
	{
		size_t len = strlen(fdata);
		memcpy(ptr, fdata, len);
		upload_ctx->lines_read++;
		return len;
	}
	return 0;
}

int main()
{
	  CURL *curl;
	  CURLcode res = CURLE_OK;
	  struct curl_slist *recipients = NULL;
	  struct fileBuf_upload_status file_upload_ctx;
	  size_t file_size(0);

	  file_upload_ctx.lines_read = 0;

	  curl = curl_easy_init();
	  file_size = read_file();

	  if(curl) 
	  {
		curl_easy_setopt(curl, CURLOPT_USERNAME, "xxxx");
		curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxx");
		curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587");
		curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
		curl_easy_setopt(curl, CURLOPT_CAINFO, "google.pem");
		curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
		recipients = curl_slist_append(recipients, TO);
		curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

		curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size); 
		curl_easy_setopt(curl, CURLOPT_READFUNCTION, fileBuf_source);
		curl_easy_setopt(curl, CURLOPT_READDATA, &file_upload_ctx);
		curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	  }
	  while(true)
	  {
		  res = curl_easy_perform(curl);
		  if(res == CURLE_OK)
		  {
			  curl_easy_cleanup(curl);
			  delete[] fileBuf;
			  break;
		  }
		  Sleep(delay);
	  }

          system("pause");
          return 0;
}



Any suggestion??

解决方案

As mentionned in solution 2, there are some memory leaks. Any memory allocated by new or new[] should be released by delete (or delete[] respectively.

And also inspired by that solution, you might have a difference between the reported file size and the actual required size like the exact handling of new lines and other spaces or partial bloc of data.

It should be relatively easy to add some validation checks for debugging purpose. For exemple, you can count the number of byte written in the file or a block and compare with expected or allocated value.

Before each appending, you can validate that there is still enough room.

You can then use a debugger and set breakpoints that will trigger when you are about to overflow a buffer.

You can also try to add some extra space to one or more of the buffer and check if the problem still occurs. If not, then maybe, your estimated size was too small. You should then verify that computed values are safe in all cases.


Check the results of fread, fseek, and ftell for errors - which can ruin your file size estimates.

Also, you have a memory leak.

char* temp_buf = new char[SEND_BUF_SIZE + 4];   //taking extra size of 4 bytes


Without seeing your code we can give little help. However you should have a look to the classical Newcomer's article: "Surviving the Release Version"[^].


这篇关于为什么在visual c ++中发布版本的代码中出现语法错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆