jmcnamara / libxlsxwriter

A C library for creating Excel XLSX files.
https://libxlsxwriter.github.io
Other
1.49k stars 332 forks source link

lxw_strdup() acess violation in Debug Mode #361

Closed LeoPollock closed 2 years ago

LeoPollock commented 2 years ago

Hi. First, thanks for the amazing library. It really helped me a lot. I am having some trouble when generating a line chart in Debug Mode. The sheet I am building varies in size from the data I have. Basically, I have two columns, one with the date(dd/mm/yy) and the other with the hour(hh:mm:ss), which I use as the category axis. Then I have three columns of floats that I use which one as a series. I set the interval tick and unit by a factor of 17 because the number of lines can be large(let's say from 100 to 1000). When generating the sheet with the chart with no options(worksheet_insert_chart(worksheet, CELL("A1"), chart);), the code works. The problem is: when I put a lxw_chart_options object to resize the chart in the sheet, the debug throws an exception because an access violation in lxw_strdup()(in strlen(str)), called on object_props->description = lxw_strdup(user_options->description); in lxw_error worksheet_insert_chart_opt(). In release mode, the code works just fine, the chart has the size that I want. I tried to add the description, dynamically allocate lxw_chart_options, with no success.

Obs.: In another part of the code, I use a similar function to generate a column chart(with less data, should I mention), and it works with lxw_error worksheet_insert_chart_opt().

Here is my code:

lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
CString strCat;
CString strSerie[3];
CString strSerieName[3];

strCat.Format("=Data!$%s$%d:$%s$%d",CExcelUtils::returnColumnCoordenate(DATE_COLUMN),firstLineData,CExcelUtils::returnColumnCoordenate(HOUR_COLUMN), countValidRegisters+firstLineData);

strSerie[0].Format("=Data!$%s$%d:$%s$%d",CExcelUtils::returnColumnCoordenate(FIRST_FP_COLUMN),firstLineData,CExcelUtils::returnColumnCoordenate(FIRST_FP_COLUMN), countValidRegisters+firstLineData);
strSerieName[0].Format("FP %.2f",(float)v_FP1/100.0);

strSerie[1].Format("=Data!$%s$%d:$%s$%d",CExcelUtils::returnColumnCoordenate(FIRST_FP_COLUMN+1),firstLineData,CExcelUtils::returnColumnCoordenate(FIRST_FP_COLUMN+1), countValidRegisters+firstLineData);
strSerieName[1].Format("FP %.2f",(float)v_FP2/100.0);

strSerie[2].Format("=Data!$%s$%d:$%s$%d",CExcelUtils::returnColumnCoordenate(FIRST_FP_COLUMN+2),firstLineData,CExcelUtils::returnColumnCoordenate(FIRST_FP_COLUMN+2), countValidRegisters+firstLineData);
strSerieName[2].Format("FP %.2f",(float)v_FP3/100.0);

lxw_chart_series *series1 = chart_add_series(chart, strCat.GetString(), strSerie[0].GetString());
chart_series_set_name(series1, strSerieName[0].GetString());

lxw_chart_series *series2 = chart_add_series(chart, strCat.GetString(), strSerie[1].GetString());
chart_series_set_name(series2, strSerieName[1].GetString());

lxw_chart_series *series3 = chart_add_series(chart, strCat.GetString(), strSerie[2].GetString());
chart_series_set_name(series3, strSerieName[2].GetString());

chart_axis_set_name(chart->x_axis, "Date");
chart_axis_set_name(chart->y_axis,"kVar necessary to correction");
chart_axis_set_label_position(chart->x_axis, LXW_CHART_AXIS_LABEL_POSITION_LOW);

chart_title_set_name(chart,"Report");
//chart_axis_set_num_format(chart->x_axis, "dd/mm/yy");
chart_axis_set_interval_tick(chart->x_axis, (int) countValidRegisters/17);
chart_axis_set_interval_unit(chart->x_axis, (int) countValidRegisters/17);
chart_axis_set_major_tick_mark(chart->x_axis, LXW_CHART_AXIS_TICK_MARK_CROSSING);
chart_axis_set_minor_tick_mark(chart->x_axis, LXW_CHART_AXIS_TICK_MARK_INSIDE);

lxw_chart_options options2;

options2.x_offset = 10;
options2.y_offset = 10;
options2.x_scale = 3.0;
options2.y_scale = 2.0;

worksheet_insert_chart_opt(worksheet, CELL("A1"), chart, &options2);
jmcnamara commented 2 years ago

This is probably an issue:

lxw_chart_options options2;

The lxw_chart_options struct should be initialized or else it will contain a lot of junk data. Something like this should work depending on your compiler:

lxw_chart_options options2 = {0};

If that isn't the issue then please add some more of the stack trace/debug log and also what compiler and environment you are using.

LeoPollock commented 2 years ago

Wow, thanks for the fast response. That was it, just had to initialize the struct. Thanks a lot. I will close the issue.