2012-03-22 61 views
5

Tôi đã phát triển một hàm trợ giúp nhỏ cho một lớp thử nghiệm đơn vị, lấy số vector<unsigned char> của mình và chuyển nó trở lại thành const char *. Tôi đã viết điều này để tôi có thể chuyển nó tới sốcủa gtest để so sánh đơn giản. Ở đây là:Chức năng C++ trả về const char *

const char * convertVecToChar(std::vector<unsigned char>& source) 
{ 
    std::vector<unsigned char>::size_type size = source.size(); 
    char* data = (char*)malloc(sizeof(char) * (size + 1)); 
    memcpy(data, &source[0], size); 
    data[size] = 0; 
    return data; 
} 

Và đây là một ví dụ của nó được gọi là:

ASSERT_STREQ("de", convertVecToChar(somevector)); 

Tôi đoán đây là rò rỉ tuy nhiên như tôi gọi malloc, nhưng mà không gọi delete tiếp tục xuống đường?

Có cách nào thanh lịch hơn để thực hiện việc này không liên quan đến việc tạo biến riêng biệt const char * cho mỗi lần tôi gọi ASSERT_STREQ trong một phương pháp thử nghiệm không?

Cảm ơn trước vì tất cả các câu trả lời.

Chris

+1

Sử dụng 'miễn phí() 'sau' malloc()', không phải 'DELETE'. – hmjd

+0

+1 cho một câu hỏi thú vị. Tôi không thực sự có một câu trả lời, mặc dù. Điều này có vẻ giống như một hack khổng lồ chỉ để thử nghiệm đơn vị. Bạn đã cân nhắc tạo một 'ASSERT_VECEQ'? Ngoài ra, có lẽ bạn không nên quan tâm quá nhiều cho rò rỉ bộ nhớ trong các bài kiểm tra đơn vị. –

+0

Được rồi, cảm ơn vì đã cho tôi biết. –

Trả lời

11

Return một std::string thay vì một char* (malloc(), hoặc new, unrequired):

std::string convertVecToChar(std::vector<unsigned char>& source) 
{ 
    return std::string(source.begin(), source.end()); 
} 

và sử dụng:

ASSERT_STREQ("de", convertVecToChar(somevector).c_str()); 
+1

Điều này dường như là cách tiếp cận thông thường :) Cảm ơn! –

1

Bạn chỉ nên sử dụng string container - không cần phải lo lắng về rò rỉ bộ nhớ.

BTW - Khi bạn đang sử dụng C++ - chỉ cần gắn vào newdelete.

0

Tôi sẽ khuyên bạn nên sử dụng std :: string quá, nhưng tôi đã tự hỏi, tại sao không chỉ so sánh nội dung của véc tơ? Bạn có thể truy cập các dữ liệu thô qua &source[0], vì vậy bạn có thể làm:

ASSERT_STREQ("de", (char*)&source[0]); 
+1

Đã thử điều này, nhưng thử nghiệm không thành công - 'ASSERT_STREQ (" de ", (const char *) & ret [0]);' - nghĩ rằng đó là vì không có byte 0 ở cuối vectơ. –

+0

@MrChris: Vâng, tôi đã không nghĩ về điều đó – MikMik

2

quá tải operator==, sau đó bạn chỉ có thể sử dụng ASSERT_EQ:

bool operator==(const char* nullTerminatedChars, 
       const std::vector<char>& vecChars) 
{ 
    return std::string(nullTerminatedChars) == 
      std::string(vecChars.begin(), vecChars.end()); 
} 

Use as:

std::vector<char> chars; 
ASSERT_EQ("de", chars); 

bạn' cũng sẽ cần quá tải operator<<(std::ostream& ..., vì GoogleTest sử dụng nó để chuyển đổi đối số thành xác nhận thông báo lỗi nếu xác nhận không thành công.

chỉnh sửa:

std::ostream& operator<<(std::ostream& os, const std::vector<char>& chars) 
{ 
    return os << std::string(chars.begin(), chars.end()); 
} 
+0

Tôi thích điều này - trông rất thanh lịch. Nhưng sẽ cần một số bài tập về nhà về cách thực hiện quá tải đúng cách! (Vẫn còn một chút của một n00b tại công cụ này). Cám ơn vì sự gợi ý. –

1
source.push_back(0); 
ASSERT_STREQ("de", (char*)&source[0]); 
source.pop_back(); 
Các vấn đề liên quan