调用使用字符数组的类函数(C ++)

时间:2016-03-12 01:49:26

标签: c++ function class object serialization

我主要使用C并且在很长一段时间内没有使用过类。我试图使用其他人创建的一些类函数,但我无法使deserialize()函数起作用。我理解它的作用,但我不能为我的生活弄清楚如何调用这个功能。我已经提供了函数以及我如何在下面调用它们。

$(function () {
    // You will need this API key in order to call the Rotten Tomatoes API.
    var apiKey = *removed for security purposes;
    var baseUrl = "http://api.rottentomatoes.com/api/public/v1.0";

    var moviesSearchUrl = baseUrl + '/lists/movies/box_office.json?apikey=' + apiKey
    document.getElementById('searchBox').addEventListener('keydown', function (event) {

        if (event.which === 13 || event.keyCode === 13) {
            var searchText = this.value;
            $(document).ready(function () {
                $.ajax("http://api.rottentomatoes.com/api/public/v1.0/movies.json", {
                    q: 'TODO put in search text',
                    page_limit: 10,
                    page: 1,
                    success: seachCallBack(),
                    dataType: 'jsonp'
                });
            });

            // callback for when we get back the results
            function searchCallback(data) {               
                var movies = data.movies;
                $.each(movies, function (index, movie) {
                    $(document.body).append('<h1>' + movie.title + '</h1>');
                    $(document.body).append('<img src="' + movie.posters.thumbnail + '" />');
                });
            }
        }
    });
});

以下是我试图让它发挥作用的方式:

//Creates a packet 
packet::packet(int t, int s, int l, char * d){
    type = t;
    seqnum = s;
    length = l;
    data = d;
}
// This function serializes the data such that type, seqnum, length, and data values are placed 
// in a char array, spacket, and separated by a single space; that is, spacket contains the serialized data
void packet::serialize(char * spacket){
        cout << "data: " << endl << endl;
    sprintf (spacket, "%d %d %d %s", type, seqnum, length, data);   
}

// This function deserializes a char array, spacket, which is the result of a call to serialize
void packet::deserialize(char * spacket){
    char * itr;
    itr = strtok(spacket," ");
    char * null_end;

    this->type = strtol(itr, &null_end, 10);

    itr = strtok(NULL, " ");
    this->seqnum = strtol (itr, &null_end, 10);

    itr = strtok(NULL, " ");
    this->length = strtol (itr, &null_end, 10);

    if(this->length == 0){
        data = NULL;
    }
    else{
        itr = strtok(NULL, ""); 
        for(int i=0; i < this->length; i++){ // copy data into char array
            this->data[i] = itr[i];
        }
    }
}

我只是不了解如何调用deserialize(),我创建了一个数据包并对其进行了序列化,该部分工作正常,但我不知道如何撤消它。我是否需要先创建一个空数据包对象?如果是这样,怎么样?我尝试过多种方式,但我无法让它发挥作用。我知道这是非常基本的,但就像我说的,我几年没有上过课。为了让序列化工作我花了很长一段时间,但我已经尝试了所有我能想到的反序列化并且卡住了。

2 个答案:

答案 0 :(得分:1)

您正在使用的课程设计得不是很好。

对于初学者,serialize()函数接受一个指向输出缓冲区的指针,而无需任何指定缓冲区大小的方法。它充满信心地认为缓冲区足够大以便于序列化&#34;数据。如果不是,它会很乐意随意记忆。

然后,deserialize()也令人印象深刻。对于初学者来说,没有自尊的反序列化器需要一个指向被反序列化的数据的可变指针。解串器应该只需要一个常量或只读指针。

当然,这个deserialize()想要一个可变缓冲区的原因是因为它会乱写,并通过strtok()覆盖它反序列化的缓冲区。这意味着您不能使用序列化对象反序列化对象的两个或多个实例,除非事先制作序列化对象的副本。

从您所显示的实际错误的位置来看,实际上并不清楚,但这很可能是因为您没有为序列化对象分配足够大的缓冲区。即使你相信&#34;它正常工作&#34;它也没有,最终破坏了内存,在代码试图反序列化已损坏的缓冲区之前,内存并不明显,导致未定义行为。

但是,如果您确实认为缓冲区足够大,那么您应该能够通过使用调试器来逐步完成代码并检查它正在做什么来自己找出答案。对于运行时涉及分段错误的问题,正确的答案是始终使用调试器,检查应用程序的运行时状态并确定问题。

答案 1 :(得分:1)

@Pongjazzle,

我同意Sam的观点,即课堂设计需要改进。但是,我认为你可以搞清楚。也许,您可能希望以这种方式来测试您的代码,假设sendbuf可以保存所有序列化的数据包数据。

packet *test = new packet(1, 4, 4, message);
test->serialize(sendbuf);

packet *test2 = new packet(0,0,0, NULL); // results in a segmentation fault currently (which is expected as the attempts to access a location referred to by a null pointer in this->data (i.e., NULL based on the object instantiation code)
test->deserialize(sendbuf);

将其更改为:

packet *test2 = new packet(0,0,0, newmessage); // assign a valid buffer
test2->deserialize(sendbuf);  // Now fill's in the values and buffer from serialized content.