# What are the internal differences between Matlab strings and character arrays?

193 views (last 30 days)
Jim Hokanson on 17 Oct 2017
Commented: Steven Lord on 6 May 2021
Matlab strings were introduced in 2016b presumably to make working with a string more similar to other languages, as compared to character arrays.
Although the documentation clearly states most details that people will want to know about a string, I'm a bit unclear as to how a string and character array are different, other than having different methods.
Presumably strings are still encoded using UTF-16. Although I haven't tried it, I wouldn't expect that mex files support strings.
Also in this post, https://blogs.mathworks.com/loren/2016/09/15/introducing-string-arrays/, Loren mentions that "string arrays" are "more efficient" for storing text data. Why? (This might be a string array question and not something specific to strings vs chars).
Steven Lord on 6 May 2021
[This may seem like a non sequiter at first, but bear with me for a moment.] Technically, the matrix product A*B is only mathematically defined if the number of columns in A matches the number of rows in B. But MATLAB breaks that rule slightly by allowing either A or B to be a scalar even if the other is not a vector. It does so in order to not force users to create (potentially large) temporary arrays.
n = 6; % Imagine if n were 600 or 6000 instead of 6
A1 = 5;
A2 = diag(repmat(A1, 1, n));
B = magic(n);
C1 = A1*B;
C2 = A2*B;
isequal(C1, C2) % true
ans = logical
1
whos % A2 is larger than A1
Name Size Bytes Class Attributes A1 1x1 8 double A2 6x6 288 double B 6x6 288 double C1 6x6 288 double C2 6x6 288 double ans 1x1 1 logical n 1x1 8 double
Technically, cellfun should only operate on cell arrays including cellstrs and should throw an error if you pass in a string array. However, in order to not force users to convert string arrays into cellstrs manually (the equivalent of creating A2 from A1) which too could be expensive in terms of time and/or memory cellfun treats those strings like they were cellstrs. This includes treating them like cellstrs for the purposes of calling class on the contents.
C = {'abc', 'def'};
cellResult = cellfun(@class, C, 'UniformOutput', false)
cellResult = 1×2 cell array
{'char'} {'char'}
Cs = string(C);
stringResult = cellfun(@class, Cs, 'UniformOutput', false) % Treats Cs like it were C
stringResult = 1×2 cell array
{'char'} {'char'}

Walter Roberson on 23 Oct 2017
When storing multiple items of text, to store it as a cell array of character vectors requires 112 bytes of overhead per item, because that is the overhead for non-empty cell array entries: cell arrays do not know ahead of time that each entry will be the same type and so has to store the type and full size information for each.
string arrays, on the other hand, need an overall size, and an overall type that applies for the entire array, but after that need only a length (not full array dimensions) and data pointer per entry.
The size also changes in ways that indicate some internal chunking:
• strings of length 0 through 10 take 132 bytes
• strings of length 11 through 15 take 142 bytes
• longer strings take an additional 16 bytes for each 8 characters or fewer
For unshared strings, this would allow small numbers of characters to be appended without reallocating, which could help performance.
Jim Hokanson on 24 Oct 2017
Edited: Jim Hokanson on 24 Oct 2017
As suggested by Yair check out this comment and its responses: https://undocumentedmatlab.com/blog/couple-of-matlab-bugs-and-workarounds#comment-340803

Steven Lord on 23 Oct 2017
For purposes of this answer, I'm going to use the word "phrase" kind of liberally to mean a chunk of textual data. That could be a character, a word, a sentence or phrase, a book, etc. A couple of differences that make string arrays more efficient to work with than char arrays:
• A string array treats each phrase as a unit, whereas a char array treats each character as a unit. In the past we've seen plenty of people do something like this:
c = 'apple';
f = c(1) % expecting f to be 'apple', but it is 'a'
With a string:
s = "apple";
f = s(1) % expecting f to be "apple", which it is
• Storing phrases of different lengths in a char matrix requires padding with blanks. This means you need to remove the padding when you want to use each phrase later on. A string array doesn't require this padding.
c = ['apple '; 'banana'; 'cherry'];
c = strvcat(c, 'watermelon');
size(c)
f = ['{' c(1, :) '}'] % Note the extra spaces between the {}
s = ["apple"; "banana"; "cherry"];
s = [s; "watermelon"];
size(s)
f1 = ['{' s(1) '}'] % Note that f1 is now a 1x3 array; each of the braces is a separate string
f2 = '{' + s(1) + '}' % Note no extra spaces between the braces and the phrase apple
• In the past one way to store multiple char arrays of different lengths without padding was to store them in a cell array. But MATLAB functions that needed to process the textual data would need to check (using something like iscellstr) whether or not every element of the cell contained a char vector. That checking takes time. A string array can only contain string data, so it doesn't need to check each element in the array for "string-ness". That extra validation probably doesn't take a lot of time, unless you need to do it often and/or on a large cell of char data.
• Regarding MEX-file support, I'm not certain. If you want to request MEX-file support for string arrays, or learn what support there is (nothing's listed in the documentation as far as I could find) I recommend contacting Technical Support directly using the Contact Us link in the upper-right corner of this page.

Yair Altman on 24 Oct 2017
Edited: Yair Altman on 24 Oct 2017
The new strings are simply Matlab classes (MCOS objects), that extend 3 superclasses (matlab.mixin.internal.MatrixDisplay, matlab.mixin.internal.indexing.Paren, matlab.mixin.internal.indexing.ParenAssign). The ability to use double quotes (") to signify strings (as in s="apple") is simply syntactic sugar for the new string class. As a class object, the new strings defines 3 dozen internal class methods, such as cellstr(), char(), split() etc.
The string class is defined with class attributes Sealed and RestrictsSubclassing, to ensure that nobody can override its behavior. Moreover, TMW was extra-careful (way more that it usually is) to close most of the doors that can be used to access the internals. It's no wonder that MathWorkers on this page ignore the explicit repeated requests for information about the internals.
The internal string data is stored inside a class property called "data", which is private and hidden and so is not regularly accessible except via the class methods. If you want to access it, you can't simply use struct(), but you could try using James Tursa's mxGetPropertyPtr, as explained here: https://undocumentedmatlab.com/blog/accessing-private-object-properties
As for the discussion above regarding the specific UTF representation, I think that you will find the following discussion interesting, especially in the comments thread: https://undocumentedmatlab.com/blog/couple-of-matlab-bugs-and-workarounds
##### 2 CommentsShow 1 older commentHide 1 older comment
Jim Hokanson on 24 Oct 2017
Edited: Jim Hokanson on 24 Oct 2017
I think with Walter's answer and this one together answer my question completely.
For reference, this info can be found by digging through:
mc = ?string

Sruthi Geetha on 23 Oct 2017
First of all Strings in MATLAB are introduced in R2017a.
The main difference between strings and character arrays is that strings can be considered a complete object, where as character arrays are a vector of chars. Therefore, the latter you can access individual characters via indexing whereas in the former case, you cannot. Example:
>> s = "hi"
s = "hi"
>> sc = 'hi'
sc = 'hi'
>> sc(1)
ans = 'h'
>> s(1)
ans = "hi"
>> s(2)
Error: Index exceeds matrix dimensions.
Steven Lord on 23 Oct 2017
The string class was introduced in release R2016b as Walter noted.
The ability to define a string using double quotes like "apple" was introduced in release R2017a. Perhaps that's what Sruthi had in mind.