Проблема, когда я копирую массив символов в другой, используя шаблон - PullRequest
2 голосов
/ 18 января 2012

Вот мой код:

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

template <class T1, class T2>
void copy2(const T1 source[], T2 destination[] , int size){
    for (int i=0 ; i < size ; ++i){
        destination[i]=static_cast<T1>(source[i]);
    }
}



int main() {

    const char one[] = "hello";
    char two[5];

    cout << "one: " << one << endl;
    cout << "two: " << two << endl;

    copy2(one, two, 6);

    cout << "one: " << one << endl;
    cout << "two: " << two << endl;


    return 0;
}

но он выводит:

one: hello

two:

one:

two: hello

Более того, массив "one" является константным и поэтому не должен изменяться.

PS: когда я запускаю массив "two"следующим образом это работает (но ПОЧЕМУ ??):

 char two[8];

Однако, когда я запускаю его обоими следующими способами, я получаю странные ошибки:

 char two[6];

или

 char two[7];

Ответы [ 2 ]

6 голосов
/ 18 января 2012

Мое лучшее предположение состоит в том, что two и one находятся в стеке рядом друг с другом следующим образом:

  t   w   o   -   -   o   n   e   -   -    -
 --------------------------------------------
|   |   |   |   |   | h | e | l | l | o | \0 |
 --------------------------------------------

Поскольку вы переполняете буфер two, передавая размер 6copy2 когда two имеет размер 5, память будет выглядеть следующим образом:

  t   w   o   -   -   o    n   e   -   -   -
 --------------------------------------------
| h | e | l | l | o | \0 | e | l | l | o | \0 |
 --------------------------------------------

Именно поэтому two, кажется, содержит «привет», а one ничего не показывает (так как два переопределенияего буфер и теперь нулевой терминатор является первым символом в one).

4 голосов
/ 18 января 2012

Чтобы иметь возможность скопировать исходный буфер в место назначения, вам нужен достаточно большой буфер назначения, чтобы вместить исходный буфер.

char two[5];

не имеет достаточно места для хранения H, E, L, L, O, \0 ---> размер 6
Итак, ваш целевой массив two должен по крайней мере иметь размер 6, в противном случае ваша программа записывает за пределы массива и вызывает неопределенное поведение.

Кроме того, вы должны инициализировать ваш исходный буфер и NULL завершить его. В противном случае он содержит ненужные символы.

char two[6]={0};

С вышеупомянутыми модификациями ваша программа работает как мне нужно.

...