Skip to content

Commit dcc6e08

Browse files
authored
Merge pull request #239 from scratchcpp/fix_value_memory_leaks
Fix #235: Fix memory leaks in Value assignment operators
2 parents f222177 + e7dbd28 commit dcc6e08

File tree

1 file changed

+49
-8
lines changed

1 file changed

+49
-8
lines changed

include/scratchcpp/value.h

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -372,76 +372,117 @@ class LIBSCRATCHCPP_EXPORT Value
372372

373373
const Value &operator=(float v)
374374
{
375+
if (m_type == Type::String)
376+
m_stringValue.~basic_string();
377+
375378
m_type = Type::Double;
376379
m_doubleValue = v;
377380
return *this;
378381
}
379382

380383
const Value &operator=(double v)
381384
{
385+
if (m_type == Type::String)
386+
m_stringValue.~basic_string();
387+
382388
m_type = Type::Double;
383389
m_doubleValue = v;
384390
return *this;
385391
}
386392

387393
const Value &operator=(int v)
388394
{
395+
if (m_type == Type::String)
396+
m_stringValue.~basic_string();
397+
389398
m_type = Type::Integer;
390399
m_intValue = v;
391400
return *this;
392401
}
393402

394403
const Value &operator=(long v)
395404
{
405+
if (m_type == Type::String)
406+
m_stringValue.~basic_string();
407+
396408
m_type = Type::Integer;
397409
m_intValue = v;
398410
return *this;
399411
}
400412

401413
const Value &operator=(bool v)
402414
{
415+
if (m_type == Type::String)
416+
m_stringValue.~basic_string();
417+
403418
m_type = Type::Bool;
404419
m_boolValue = v;
405420
return *this;
406421
}
407422

408423
const Value &operator=(const std::string &v)
409424
{
410-
m_type = Type::String;
411-
new (&m_stringValue) std::string(v);
425+
if (m_type == Type::String)
426+
m_stringValue = v;
427+
else {
428+
new (&m_stringValue) std::string(v);
429+
m_type = Type::String;
430+
}
431+
412432
initString(v);
413433
return *this;
414434
}
415435

416436
const Value &operator=(const char *v)
417437
{
418-
m_type = Type::String;
419-
new (&m_stringValue) std::string(v);
438+
if (m_type == Type::String)
439+
m_stringValue = v;
440+
else {
441+
new (&m_stringValue) std::string(v);
442+
m_type = Type::String;
443+
}
444+
420445
initString(v);
421446
return *this;
422447
}
423448

424449
const Value &operator=(const Value &v)
425450
{
426-
m_type = v.m_type;
427-
428-
switch (m_type) {
451+
switch (v.m_type) {
429452
case Type::Integer:
453+
if (m_type == Type::String)
454+
m_stringValue.~basic_string();
455+
430456
m_intValue = v.m_intValue;
431457
break;
458+
432459
case Type::Double:
460+
if (m_type == Type::String)
461+
m_stringValue.~basic_string();
462+
433463
m_doubleValue = v.m_doubleValue;
434464
break;
465+
435466
case Type::Bool:
467+
if (m_type == Type::String)
468+
m_stringValue.~basic_string();
469+
436470
m_boolValue = v.m_boolValue;
437471
break;
472+
438473
case Type::String:
439-
new (&m_stringValue) std::string(v.m_stringValue);
474+
if (m_type == Type::String)
475+
m_stringValue = v.m_stringValue;
476+
else
477+
new (&m_stringValue) std::string(v.m_stringValue);
440478
break;
479+
441480
default:
442481
break;
443482
}
444483

484+
m_type = v.m_type;
485+
445486
return *this;
446487
}
447488

0 commit comments

Comments
 (0)